]>
Commit | Line | Data |
---|---|---|
4c1582cf KS |
1 | use nihav_core::codecs::*; |
2 | use nihav_core::io::codebook::*; | |
3 | use nihav_codec_support::dsp::fft::*; | |
4 | use super::qdmcommon::*; | |
5 | use super::qdm2::TONE_SCALES; | |
6 | use std::f32::consts::PI; | |
7 | ||
8 | struct Codebooks { | |
9 | group_cb: [Codebook<u8>; 5], | |
10 | level_exp_alt_cb: Codebook<u8>, | |
11 | level_exp_cb: Codebook<u8>, | |
12 | stereo_exp_cb: Codebook<u8>, | |
13 | phase_diff_cb: Codebook<u8>, | |
14 | } | |
15 | ||
16 | fn map_idx(idx: usize) -> u8 { idx as u8 } | |
17 | ||
18 | macro_rules! create_codebook { | |
19 | ($codes: expr, $bits: expr) => ({ | |
20 | let mut cbr = TableCodebookDescReader::new($codes, $bits, map_idx); | |
21 | Codebook::new(&mut cbr, CodebookMode::LSB).unwrap() | |
22 | }) | |
23 | } | |
24 | ||
25 | impl Codebooks { | |
26 | fn new() -> Self { | |
27 | let cb0 = create_codebook!(FFT_GROUP_CODES[0], FFT_GROUP_BITS[0]); | |
28 | let cb1 = create_codebook!(FFT_GROUP_CODES[1], FFT_GROUP_BITS[1]); | |
29 | let cb2 = create_codebook!(FFT_GROUP_CODES[2], FFT_GROUP_BITS[2]); | |
30 | let cb3 = create_codebook!(FFT_GROUP_CODES[3], FFT_GROUP_BITS[3]); | |
31 | let cb4 = create_codebook!(FFT_GROUP_CODES[4], FFT_GROUP_BITS[4]); | |
32 | let group_cb = [cb0, cb1, cb2, cb3, cb4]; | |
33 | let level_exp_alt_cb = create_codebook!(FFT_LEVEL_EXP_ALT_CODES, FFT_LEVEL_EXP_ALT_BITS); | |
34 | let level_exp_cb = create_codebook!(FFT_LEVEL_EXP_CODES, FFT_LEVEL_EXP_BITS); | |
35 | let stereo_exp_cb = create_codebook!(FFT_STEREO_EXP_CODES, FFT_STEREO_EXP_BITS); | |
36 | let phase_diff_cb = create_codebook!(FFT_STEREO_PHASE_CODES, FFT_STEREO_PHASE_BITS); | |
37 | Self { | |
38 | group_cb, level_exp_alt_cb, level_exp_cb, | |
39 | stereo_exp_cb, phase_diff_cb, | |
40 | } | |
41 | } | |
42 | } | |
43 | ||
44 | #[derive(Clone,Copy)] | |
45 | struct OldTone { | |
46 | used: bool, | |
47 | phase: i32, | |
48 | phase_add: i32, | |
49 | time: u8, | |
50 | scale: f32, | |
51 | cutoff: usize, | |
52 | grp: u8, | |
53 | offset: u8, | |
54 | freq: u16, | |
55 | ch: u8, | |
56 | } | |
57 | ||
58 | struct Synth { | |
59 | rdft: RDFT, | |
60 | sbuf: [[FFTComplex; 256]; 2], | |
61 | delay: [[f32; 256]; 2], | |
62 | } | |
63 | ||
64 | impl Synth { | |
65 | fn new() -> Self { | |
66 | Self { | |
67 | rdft: RDFTBuilder::new_rdft(256, true, true), | |
68 | sbuf: [[FFTC_ZERO; 256]; 2], | |
69 | delay: [[0.0; 256]; 2], | |
70 | } | |
71 | } | |
72 | fn new_sf(&mut self) { | |
73 | self.sbuf = [[FFTC_ZERO; 256]; 2]; | |
74 | } | |
75 | fn synth_old_tone(&mut self, tone: &mut OldTone) { | |
76 | let off = tone.offset as usize; | |
77 | let scale = tone.scale * TONE_ENVELOPE[tone.grp as usize][tone.time as usize]; | |
78 | tone.phase += tone.phase_add; | |
79 | ||
80 | let val = FFTComplex::exp((tone.phase as f32) * PI / 256.0).scale(scale); | |
81 | let ch = tone.ch as usize; | |
82 | ||
83 | if tone.grp >= 3 || tone.cutoff >= 3 { | |
84 | self.sbuf[ch][off] += val; | |
85 | self.sbuf[ch][off + 1] -= val; | |
86 | } else { | |
87 | let tab = &FFT_TONE_SAMPLES[tone.grp as usize][(tone.freq as usize) - (off << (4 - tone.grp))]; | |
88 | let wave = [tab[3] - tab[0], -tab[4], 1.0 - tab[2] - tab[3], | |
89 | tab[1] + tab[4] - 1.0, tab[0] - tab[1], tab[2]]; | |
90 | let cidx = CUTOFF_INDICES[tone.cutoff]; | |
91 | let coff0 = (off as isize) + (cidx[0] as isize); | |
92 | let coff1 = (off as isize) + (cidx[1] as isize); | |
93 | if coff0 >= 0 { | |
94 | let imw = if tone.cutoff == 0 { -wave[0] } else { wave[0] }; | |
95 | self.sbuf[ch][coff0 as usize].re += val.re * wave[0]; | |
96 | self.sbuf[ch][coff0 as usize].im += val.im * imw; | |
97 | } | |
98 | if coff1 >= 0 { | |
99 | let imw = if tone.cutoff <= 1 { -wave[1] } else { wave[1] }; | |
100 | self.sbuf[ch][coff1 as usize].re += val.re * wave[1]; | |
101 | self.sbuf[ch][coff1 as usize].im += val.im * imw; | |
102 | } | |
103 | for i in 0..4 { | |
104 | self.sbuf[ch][off + i] += val.scale(wave[i + 2]); | |
105 | } | |
106 | } | |
107 | tone.time += 1; | |
108 | if tone.time >= (1 << (5 - tone.grp)) - 1 { | |
109 | tone.used = false; | |
110 | } | |
111 | } | |
112 | fn synth_tone(&mut self, tone: &mut Tone, cutoff: usize, scale: f32, off: usize, grp: usize) -> Option<OldTone> { | |
113 | let mut old_tone = OldTone { | |
114 | used: true, | |
115 | phase: 64 * i32::from(tone.phase) - (off as i32) * 256 - 128, | |
116 | phase_add: (2 * i32::from(tone.freq) + 1) << (grp + 3), | |
117 | grp: grp as u8, | |
118 | time: 0, | |
119 | scale, | |
120 | cutoff, | |
121 | offset: off as u8, | |
122 | ch: tone.ch, | |
123 | freq: tone.freq, | |
124 | }; | |
125 | self.synth_old_tone(&mut old_tone); | |
126 | if old_tone.used { | |
127 | Some(old_tone) | |
128 | } else { | |
129 | None | |
130 | } | |
131 | } | |
132 | fn synth_tone4(&mut self, tone: Tone, scale: f32) { | |
133 | let ch = tone.ch as usize; | |
134 | let val = FFTComplex::exp(f32::from(tone.phase) * PI * 0.25).scale(scale); | |
135 | let offset = tone.freq as usize; | |
136 | self.sbuf[ch][offset] += val; | |
137 | self.sbuf[ch][offset + 1] -= val; | |
138 | } | |
139 | fn synth_rdft(&mut self, dst: &mut [f32], ch: usize, len: usize) { | |
140 | self.sbuf[ch][0].re *= 2.0; | |
141 | self.sbuf[ch][0].im = 0.0; | |
142 | self.rdft.do_rdft_inplace(&mut self.sbuf[ch]); | |
143 | let scale = 1.0 / 2.0; | |
144 | for ((src, dly), dst) in self.sbuf[ch].iter().take(len / 2).zip(self.delay[ch].chunks(2)).zip(dst.chunks_mut(2)) { | |
145 | dst[0] += src.re * scale + dly[0]; | |
146 | dst[1] += src.im * scale + dly[1]; | |
147 | } | |
148 | for (src, dly) in self.sbuf[ch].iter().skip(len / 2).take(len / 2).zip(self.delay[ch].chunks_mut(2)) { | |
149 | dly[0] = src.re * scale; | |
150 | dly[1] = src.im * scale; | |
151 | } | |
152 | } | |
153 | } | |
154 | ||
155 | pub struct QDM2FFT { | |
156 | cbs: Codebooks, | |
157 | synth: Synth, | |
158 | packet_size: usize, | |
159 | frame_size: usize, | |
160 | channels: usize, | |
161 | subsampling: u8, | |
162 | freq_range: usize, | |
163 | ||
164 | fft_levels: [u8; 6], | |
165 | ||
166 | tones: [Vec<Tone>; 5], | |
167 | tone_start: [usize; 5], | |
168 | old_tones: Vec<OldTone>, | |
169 | ||
170 | pub is_intra: bool, | |
171 | frame_bits: u8, | |
172 | } | |
173 | ||
174 | impl QDM2FFT { | |
175 | pub fn new() -> Self { | |
176 | Self { | |
177 | cbs: Codebooks::new(), | |
178 | synth: Synth::new(), | |
179 | packet_size: 0, | |
180 | frame_size: 0, | |
181 | channels: 0, | |
182 | subsampling: 0, | |
183 | freq_range: 0, | |
184 | ||
185 | fft_levels: [0; 6], | |
186 | tones: [Vec::with_capacity(MAX_TONES), | |
187 | Vec::with_capacity(MAX_TONES), | |
188 | Vec::with_capacity(MAX_TONES), | |
189 | Vec::with_capacity(MAX_TONES), | |
190 | Vec::with_capacity(MAX_TONES)], | |
191 | tone_start: [0; 5], | |
192 | old_tones: Vec::new(), | |
193 | ||
194 | is_intra: false, | |
195 | frame_bits: 0, | |
196 | } | |
197 | } | |
198 | pub fn set_params(&mut self, channels: usize, packet_size: usize, subsampling: u8) { | |
199 | self.subsampling = subsampling; | |
200 | self.channels = channels; | |
201 | self.synth.rdft = RDFTBuilder::new_rdft(packet_size, false, true); | |
202 | self.packet_size = packet_size; | |
203 | self.frame_size = packet_size * 16; | |
204 | self.frame_bits = (31 - (self.frame_size.leading_zeros() & 31)) as u8; | |
205 | self.freq_range = 255 >> (2 - self.subsampling); | |
206 | } | |
207 | pub fn read_type_13(&mut self, br: &mut QdmBitReader) -> DecoderResult<()> { | |
208 | for el in self.fft_levels.iter_mut() { | |
209 | *el = br.read(6) as u8; | |
210 | } | |
211 | Ok(()) | |
212 | } | |
213 | pub fn read_type_14(&mut self, br: &mut QdmBitReader) -> DecoderResult<()> { | |
214 | for el in self.fft_levels.iter_mut() { | |
215 | *el = br.read_code(&self.cbs.level_exp_cb)? as u8; | |
216 | } | |
217 | Ok(()) | |
218 | } | |
219 | fn read_tones(&mut self, br: &mut QdmBitReader, group: usize, use_cb2: bool) -> DecoderResult<()> { | |
220 | let group_bits = 4 - group; | |
221 | let group_size = 1 << (self.frame_bits - (group as u8)); | |
222 | let mut freq = 1; | |
223 | let mut pos2 = 0; | |
224 | let mut offset = 0; | |
225 | let level_cb = if use_cb2 { &self.cbs.level_exp_cb } else { &self.cbs.level_exp_alt_cb }; | |
226 | while freq < self.frame_size { | |
227 | if self.is_intra { | |
228 | let mut diff = 0; | |
229 | while diff < 2 { | |
230 | diff = br.read_code_long(&self.cbs.group_cb[group_bits])?; | |
231 | if diff >= 2 { break; } | |
232 | freq = 1; | |
233 | if diff == 0 { | |
234 | pos2 += group_size; | |
235 | offset += 1 << group_bits; | |
236 | } else { | |
237 | pos2 += 8 * group_size; | |
238 | offset += 8 << group_bits; | |
239 | } | |
240 | if pos2 >= self.frame_size { | |
241 | return Ok(()); | |
242 | } | |
243 | } | |
244 | freq += (diff - 2) as usize; | |
245 | } else { | |
246 | let diff = br.read_code_long(&self.cbs.group_cb[group_bits])?; | |
247 | freq += diff as usize; | |
248 | while freq >= group_size - 1 { | |
249 | freq -= group_size - 2; | |
250 | pos2 += group_size; | |
251 | offset += 1 << group_bits; | |
252 | } | |
253 | } | |
254 | if pos2 >= self.frame_size { | |
255 | return Ok(()); | |
256 | } | |
257 | ||
258 | let pos = freq >> group_bits; | |
259 | if pos > LEVEL_INDEX.len() - 1 { | |
260 | return Ok(()); | |
261 | } | |
262 | let stereo_mode = if self.channels == 2 { | |
263 | br.read(2) as u8 | |
264 | } else { 0 }; | |
265 | ||
266 | let mut amp = br.read_code(&level_cb)? as i8; | |
267 | amp += self.fft_levels[LEVEL_INDEX[pos] as usize] as i8; | |
268 | if amp < 0 { | |
269 | amp = 0; | |
270 | } | |
271 | let phase = br.read(3) as u8; | |
272 | let (amp2, phase2) = if stereo_mode > 1 { | |
273 | let amp_diff = br.read_code(&self.cbs.stereo_exp_cb)? as i8; | |
274 | let phase_diff = br.read_code(&self.cbs.phase_diff_cb)? as i8; | |
275 | let mut p2 = (phase as i8) - phase_diff; | |
276 | if p2 < 0 { p2 += 8; } | |
277 | (amp - amp_diff, p2 as u8) | |
278 | } else { (0, 0) }; | |
279 | ||
280 | if pos <= self.freq_range { | |
281 | if self.tones[group].len() >= MAX_TONES { return Ok(()); } | |
282 | self.tones[group].push(Tone { freq: freq as u16, offset, phase, ch: stereo_mode & 1, amp_idx: amp as u8 }); | |
283 | if stereo_mode > 1 { | |
284 | if self.tones[group].len() >= MAX_TONES { return Ok(()); } | |
285 | self.tones[group].push(Tone { freq: freq as u16, offset, phase: phase2, ch: !stereo_mode & 1, amp_idx: amp2 as u8 }); | |
286 | } | |
287 | } | |
288 | ||
289 | freq += 1; | |
290 | } | |
291 | Ok(()) | |
292 | } | |
293 | pub fn new_frame(&mut self) { | |
294 | for tones in self.tones.iter_mut() { | |
295 | tones.clear(); | |
296 | } | |
297 | self.tone_start = [0; 5]; | |
298 | } | |
299 | pub fn read_fft_packet(&mut self, id: u8, br: &mut QdmBitReader) -> DecoderResult<()> { | |
300 | match id { | |
301 | 17..=23 => { | |
302 | let grp = i16::from(self.subsampling) + 4 - i16::from(id - 17); | |
303 | if grp >= 0 && grp < 5 { | |
304 | self.read_tones(br, grp as usize, false)?; | |
305 | } | |
306 | }, | |
307 | 31 => { | |
308 | for grp in 0..5 { | |
309 | self.read_tones(br, grp, false)?; | |
310 | } | |
311 | }, | |
312 | 33..=39 => { | |
313 | let grp = i16::from(self.subsampling) + 4 - i16::from(id - 33); | |
314 | if grp >= 0 && grp < 5 { | |
315 | self.read_tones(br, grp as usize, true)?; | |
316 | } | |
317 | }, | |
318 | 46 => { | |
319 | for el in self.fft_levels.iter_mut() { | |
320 | *el = br.read(6) as u8; | |
321 | } | |
322 | for grp in 0..5 { | |
323 | self.read_tones(br, grp, true)?; | |
324 | } | |
325 | }, | |
326 | _ => {}, | |
327 | }; | |
328 | Ok(()) | |
329 | } | |
330 | pub fn generate_tones(&mut self, sf: usize) { | |
331 | self.synth.new_sf(); | |
332 | self.old_tones.retain(|el| el.used); | |
333 | ||
334 | for otone in self.old_tones.iter_mut() { | |
335 | self.synth.synth_old_tone(otone); | |
336 | } | |
337 | ||
338 | let sf_idx = (sf + 0xE) & 0xF; | |
339 | let scales = if self.is_intra { &TONE_SCALES[0] } else { &TONE_SCALES[1] }; | |
340 | for group in 0..4 { | |
341 | let group_bits = 4 - group; | |
342 | for tone in self.tones[group].iter_mut().skip(self.tone_start[group]) { | |
343 | if (tone.offset as usize) > sf_idx { | |
344 | break; | |
345 | } | |
346 | ||
347 | let off = (tone.freq >> group_bits) as usize; | |
348 | if off < self.freq_range { | |
349 | let cutoff = if off < 2 { off } else if off < 60 { 2 } else { 3 }; | |
350 | let scale = scales[(tone.amp_idx & 0x3F) as usize]; | |
351 | let otone = self.synth.synth_tone(tone, cutoff, scale, off, group); | |
352 | if let Some(otone) = otone { | |
353 | self.old_tones.push(otone); | |
354 | } | |
355 | } | |
356 | ||
357 | self.tone_start[group] += 1; | |
358 | } | |
359 | } | |
360 | { | |
361 | let group = 4; | |
362 | for tone in self.tones[group].iter().skip(self.tone_start[group]) { | |
363 | if (tone.offset as usize) > sf_idx { | |
364 | break; | |
365 | } | |
366 | let scale = scales[(tone.amp_idx & 0x3F) as usize]; | |
367 | self.synth.synth_tone4(*tone, scale); | |
368 | self.tone_start[group] += 1; | |
369 | } | |
370 | } | |
371 | } | |
372 | pub fn synth(&mut self, dst: &mut [f32], ch: usize) { | |
373 | self.synth.synth_rdft(dst, ch, self.packet_size); | |
374 | } | |
375 | pub fn flush(&mut self) { | |
376 | } | |
377 | } | |
378 | ||
379 | const FFT_GROUP_CODES: [&[u16]; 5] = [ | |
380 | &[ | |
381 | 0x038E, 0x0001, 0x0000, 0x0022, 0x000A, 0x0006, 0x0012, 0x0002, | |
382 | 0x001E, 0x003E, 0x0056, 0x0016, 0x000E, 0x0032, 0x0072, 0x0042, | |
383 | 0x008E, 0x004E, 0x00F2, 0x002E, 0x0036, 0x00C2, 0x018E | |
384 | ], | |
385 | &[ | |
386 | 0x07A4, 0x0001, 0x0020, 0x0012, 0x001C, 0x0008, 0x0006, 0x0010, | |
387 | 0x0000, 0x0014, 0x0004, 0x0032, 0x0070, 0x000C, 0x0002, 0x003A, | |
388 | 0x001A, 0x002C, 0x002A, 0x0022, 0x0024, 0x000A, 0x0064, 0x0030, | |
389 | 0x0062, 0x00A4, 0x01A4, 0x03A4 | |
390 | ], | |
391 | &[ | |
392 | 0x1760, 0x0001, 0x0000, 0x0082, 0x000C, 0x0006, 0x0003, 0x0007, | |
393 | 0x0008, 0x0004, 0x0010, 0x0012, 0x0022, 0x001A, 0x0000, 0x0020, | |
394 | 0x000A, 0x0040, 0x004A, 0x006A, 0x002A, 0x0042, 0x0002, 0x0060, | |
395 | 0x00AA, 0x00E0, 0x00C2, 0x01C2, 0x0160, 0x0360, 0x0760, 0x0F60 | |
396 | ], | |
397 | &[ | |
398 | 0x33EA, 0x0005, 0x0000, 0x000C, 0x0000, 0x0006, 0x0003, 0x0008, | |
399 | 0x0002, 0x0001, 0x0004, 0x0007, 0x001A, 0x000F, 0x001C, 0x002C, | |
400 | 0x000A, 0x001D, 0x002D, 0x002A, 0x000D, 0x004C, 0x008C, 0x006A, | |
401 | 0x00CD, 0x004D, 0x00EA, 0x020C, 0x030C, 0x010C, 0x01EA, 0x07EA, | |
402 | 0x0BEA, 0x03EA, 0x13EA | |
403 | ], | |
404 | &[ | |
405 | 0x5282, 0x0016, 0x0000, 0x0136, 0x0004, 0x0000, 0x0007, 0x000A, | |
406 | 0x000E, 0x0003, 0x0001, 0x000D, 0x0006, 0x0009, 0x0012, 0x0005, | |
407 | 0x0025, 0x0022, 0x0015, 0x0002, 0x0076, 0x0035, 0x0042, 0x00C2, | |
408 | 0x0182, 0x00B6, 0x0036, 0x03C2, 0x0482, 0x01C2, 0x0682, 0x0882, | |
409 | 0x0A82, 0x0082, 0x0282, 0x1282, 0x3282, 0x2282 | |
410 | ] | |
411 | ]; | |
412 | const FFT_GROUP_BITS: [&[u8]; 5] = [ | |
413 | &[ | |
414 | 10, 1, 2, 6, 4, 5, 6, 7, 6, 6, 7, 7, 8, 7, 8, 8, | |
415 | 9, 7, 8, 6, 6, 8, 10 | |
416 | ], | |
417 | &[ | |
418 | 11, 1, 6, 6, 5, 4, 3, 6, 6, 5, 6, 6, 7, 6, 6, 6, | |
419 | 6, 6, 6, 7, 8, 6, 7, 7, 7, 9, 10, 11 | |
420 | ], | |
421 | &[ | |
422 | 13, 2, 0, 8, 4, 3, 3, 3, 4, 4, 5, 5, 6, 5, 7, 7, | |
423 | 7, 7, 7, 7, 8, 8, 8, 9, 8, 8, 9, 9, 10, 11, 13, 12 | |
424 | ], | |
425 | &[ | |
426 | 14, 4, 0, 10, 4, 3, 3, 4, 4, 3, 4, 4, 5, 4, 5, 6, | |
427 | 6, 5, 6, 7, 7, 7, 8, 8, 8, 8, 9, 10, 10, 10, 10, 11, | |
428 | 12, 13, 14 | |
429 | ], | |
430 | &[ | |
431 | 15, 6, 0, 9, 3, 3, 3, 4, 4, 3, 4, 4, 5, 4, 5, 6, | |
432 | 6, 6, 6, 8, 7, 6, 8, 9, 9, 8, 9, 10, 11, 10, 11, 12, | |
433 | 12, 12, 14, 15, 14, 14 | |
434 | ] | |
435 | ]; | |
436 | ||
437 | const FFT_LEVEL_EXP_ALT_CODES: &[u16; 28] = &[ | |
438 | 0x1EC6, 0x0006, 0x00C2, 0x0142, 0x0242, 0x0246, 0x00C6, 0x0046, | |
439 | 0x0042, 0x0146, 0x00A2, 0x0062, 0x0026, 0x0016, 0x000E, 0x0005, | |
440 | 0x0004, 0x0003, 0x0000, 0x0001, 0x000A, 0x0012, 0x0002, 0x0022, | |
441 | 0x01C6, 0x02C6, 0x06C6, 0x0EC6 | |
442 | ]; | |
443 | const FFT_LEVEL_EXP_ALT_BITS: &[u8; 28] = &[ | |
444 | 13, 7, 8, 9, 10, 10, 10, 10, 10, 9, 8, 7, 6, 5, 4, 3, | |
445 | 3, 2, 3, 3, 4, 5, 7, 8, 9, 11, 12, 13 | |
446 | ]; | |
447 | ||
448 | const FFT_LEVEL_EXP_CODES: &[u16; 20] = &[ | |
449 | 0x0F24, 0x0001, 0x0002, 0x0000, 0x0006, 0x0005, 0x0007, 0x000C, | |
450 | 0x000B, 0x0014, 0x0013, 0x0004, 0x0003, 0x0023, 0x0064, 0x00A4, | |
451 | 0x0024, 0x0124, 0x0324, 0x0724 | |
452 | ]; | |
453 | const FFT_LEVEL_EXP_BITS: &[u8; 20] = &[ | |
454 | 12, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 9, 10, 11, 12 | |
455 | ]; | |
456 | ||
457 | const FFT_STEREO_EXP_CODES: &[u8; 7] = &[ 0x3E, 0x01, 0x00, 0x02, 0x06, 0x0E, 0x1E ]; | |
458 | const FFT_STEREO_EXP_BITS: &[u8; 7] = &[ 6, 1, 2, 3, 4, 5, 6 ]; | |
459 | ||
460 | const FFT_STEREO_PHASE_CODES: &[u8; 9] = &[ | |
461 | 0x35, 0x02, 0x00, 0x01, 0x0D, 0x15, 0x05, 0x09, 0x03 | |
462 | ]; | |
463 | const FFT_STEREO_PHASE_BITS: &[u8; 9] = &[ 6, 2, 2, 4, 4, 6, 5, 4, 2 ]; | |
464 | ||
465 | const CUTOFF_INDICES: [[i8; 2]; 4] = [ [1, 2], [-1, 0], [-1,-2], [0, 0] ]; | |
466 | ||
467 | const LEVEL_INDEX: [u8; 256] = [ | |
468 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, | |
469 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
470 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
471 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
472 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
473 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
474 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
475 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
476 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
477 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
478 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
479 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
480 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
481 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
482 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
483 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 | |
484 | ]; | |
485 | ||
486 | const FFT_TONE_SAMPLES: [[[f32; 5]; 16]; 4] = [ | |
487 | [ | |
488 | [ 0.0100000000,-0.0037037037,-0.0020000000,-0.0069444444,-0.0018416207 ], | |
489 | [ 0.0416666667, 0.0000000000, 0.0000000000,-0.0208333333,-0.0123456791 ], | |
490 | [ 0.1250000000, 0.0558035709, 0.0330687836,-0.0164473690,-0.0097465888 ], | |
491 | [ 0.1562500000, 0.0625000000, 0.0370370370,-0.0062500000,-0.0037037037 ], | |
492 | [ 0.1996007860, 0.0781250000, 0.0462962948, 0.0022727272, 0.0013468013 ], | |
493 | [ 0.2000000000, 0.0625000000, 0.0370370373, 0.0208333333, 0.0074074073 ], | |
494 | [ 0.2127659619, 0.0555555556, 0.0329218097, 0.0208333333, 0.0123456791 ], | |
495 | [ 0.2173913121, 0.0473484844, 0.0280583613, 0.0347222239, 0.0205761325 ], | |
496 | [ 0.2173913121, 0.0347222239, 0.0205761325, 0.0473484844, 0.0280583613 ], | |
497 | [ 0.2127659619, 0.0208333333, 0.0123456791, 0.0555555556, 0.0329218097 ], | |
498 | [ 0.2000000000, 0.0208333333, 0.0074074073, 0.0625000000, 0.0370370370 ], | |
499 | [ 0.1996007860, 0.0022727272, 0.0013468013, 0.0781250000, 0.0462962948 ], | |
500 | [ 0.1562500000,-0.0062500000,-0.0037037037, 0.0625000000, 0.0370370370 ], | |
501 | [ 0.1250000000,-0.0164473690,-0.0097465888, 0.0558035709, 0.0330687836 ], | |
502 | [ 0.0416666667,-0.0208333333,-0.0123456791, 0.0000000000, 0.0000000000 ], | |
503 | [ 0.0100000000,-0.0069444444,-0.0018416207,-0.0037037037,-0.0020000000 ] | |
504 | ], [ | |
505 | [ 0.0050000000,-0.0200000000, 0.0125000000,-0.3030303030, 0.0020000000 ], | |
506 | [ 0.1041666642, 0.0400000000,-0.0250000000, 0.0333333333,-0.0200000000 ], | |
507 | [ 0.1250000000, 0.0100000000, 0.0142857144,-0.0500000007,-0.0200000000 ], | |
508 | [ 0.1562500000,-0.0006250000,-0.00049382716,-0.000625000,-0.00049382716 ], | |
509 | [ 0.1562500000,-0.0006250000,-0.00049382716,-0.000625000,-0.00049382716 ], | |
510 | [ 0.1250000000,-0.0500000000,-0.0200000000, 0.0100000000, 0.0142857144 ], | |
511 | [ 0.1041666667, 0.0333333333,-0.0200000000, 0.0400000000,-0.0250000000 ], | |
512 | [ 0.0050000000,-0.3030303030, 0.0020000001,-0.0200000000, 0.0125000000 ], | |
513 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
514 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
515 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
516 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
517 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
518 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
519 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
520 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ] | |
521 | ], [ | |
522 | [ 0.1428571492, 0.1250000000,-0.0285714287,-0.0357142873, 0.0208333333 ], | |
523 | [ 0.1818181818, 0.0588235296, 0.0333333333, 0.0212765951, 0.0100000000 ], | |
524 | [ 0.1818181818, 0.0212765951, 0.0100000000, 0.0588235296, 0.0333333333 ], | |
525 | [ 0.1428571492,-0.0357142873, 0.0208333333, 0.1250000000,-0.0285714287 ], | |
526 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
527 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
528 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
529 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
530 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
531 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
532 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
533 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
534 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
535 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
536 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
537 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ] | |
538 | ], [ | |
539 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
540 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
541 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
542 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
543 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
544 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
545 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
546 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
547 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
548 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
549 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
550 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
551 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
552 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
553 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ], | |
554 | [ 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000 ] | |
555 | ] | |
556 | ]; | |
557 | ||
558 | const TONE_ENVELOPE: [[f32; 31]; 4] = [ | |
559 | [ | |
560 | 0.009607375, 0.038060248, 0.084265202, 0.146446645, | |
561 | 0.222214907, 0.308658302, 0.402454883, 0.500000060, | |
562 | 0.597545207, 0.691341758, 0.777785182, 0.853553414, | |
563 | 0.915734828, 0.961939812, 0.990392685, 1.00000000, | |
564 | 0.990392625, 0.961939752, 0.915734768, 0.853553295, | |
565 | 0.777785063, 0.691341639, 0.597545087, 0.500000000, | |
566 | 0.402454853, 0.308658272, 0.222214878, 0.146446615, | |
567 | 0.084265172, 0.038060218, 0.009607345 | |
568 | ], [ | |
569 | 0.038060248, 0.146446645, 0.308658302, 0.500000060, | |
570 | 0.691341758, 0.853553414, 0.961939812, 1.00000000, | |
571 | 0.961939752, 0.853553295, 0.691341639, 0.500000000, | |
572 | 0.308658272, 0.146446615, 0.038060218, 0.000000000, | |
573 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
574 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
575 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
576 | 0.000000000, 0.000000000, 0.000000000 | |
577 | ], [ | |
578 | 0.146446645, 0.500000060, 0.853553414, 1.00000000, | |
579 | 0.853553295, 0.500000000, 0.146446615, 0.000000000, | |
580 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
581 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
582 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
583 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
584 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
585 | 0.000000000, 0.000000000, 0.000000000 | |
586 | ], [ | |
587 | 0.500000060, 1.00000000, 0.500000000, 0.000000000, | |
588 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
589 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
590 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
591 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
592 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
593 | 0.000000000, 0.000000000, 0.000000000, 0.000000000, | |
594 | 0.000000000, 0.000000000, 0.000000000 | |
595 | ] | |
596 | ]; |