]> git.nihav.org Git - nihav.git/blame_incremental - nihav-qt/src/codecs/qdm2.rs
aac: fix intensity stereo reconstruction for ms_mask_present=0 case
[nihav.git] / nihav-qt / src / codecs / qdm2.rs
... / ...
CommitLineData
1use nihav_core::codecs::*;
2use nihav_core::io::byteio::*;
3use super::qdmcommon::*;
4use super::qdm2fft::*;
5use super::qdm2qmf::*;
6
7pub const MAX_FRAME_SIZE: usize = 8192;
8
9const SOFTCLIP_THRESHOLD: usize = 27600;
10const HARDCLIP_THRESHOLD: usize = 35716;
11const SOFTCLIP_SIZE: usize = HARDCLIP_THRESHOLD - SOFTCLIP_THRESHOLD + 1;
12
13#[derive(Clone,Copy)]
14struct Packet {
15 id: u8,
16 size: usize,
17 offset: usize,
18}
19
20impl Packet {
21 fn read(br: &mut ByteReader) -> DecoderResult<Self> {
22 let id = br.read_byte()?;
23 let size = if (id & 0x80) == 0 { br.read_byte()? as usize } else { br.read_u16be()? as usize };
24 validate!(size <= (br.left() as usize));
25 Ok(Packet { id: id & 0x7F, size, offset: br.tell() as usize })
26 }
27}
28
29struct Qdmc2Decoder {
30 ainfo: NAAudioInfo,
31 chmap: NAChannelMap,
32 softclip: [i16; SOFTCLIP_SIZE],
33 qmf_part: QDM2QMF,
34 fft_part: QDM2FFT,
35 audio: [[f32; MAX_FRAME_SIZE]; 2],
36
37 order: u8,
38 frame_bits: u8,
39 samples: usize,
40 frm_bytes: usize,
41 sf_len: usize,
42 channels: usize,
43
44 subsampling: u8,
45 do_synth: bool,
46}
47
48impl Qdmc2Decoder {
49 fn new() -> Self {
50 let mut softclip = [0; SOFTCLIP_SIZE];
51 let delta = 1.0 / ((32767 - SOFTCLIP_THRESHOLD) as f32);
52 let diff = f32::from((SOFTCLIP_THRESHOLD as i16) - 32767);
53 for (i, el) in softclip.iter_mut().enumerate() {
54 *el = (SOFTCLIP_THRESHOLD as i16) - ((((i as f32) * delta).sin() * diff) as i16);
55 }
56
57 Self {
58 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 1),
59 chmap: NAChannelMap::new(),
60 audio: [[0.0; MAX_FRAME_SIZE]; 2],
61 softclip,
62 qmf_part: QDM2QMF::new(),
63 fft_part: QDM2FFT::new(),
64
65 order: 0,
66 frame_bits: 0,
67 samples: 0,
68 frm_bytes: 0,
69 sf_len: 0,
70 channels: 0,
71
72 subsampling: 0,
73 do_synth: false,
74 }
75 }
76}
77
78impl NADecoder for Qdmc2Decoder {
79 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
80 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
81 if let Some(edata) = info.get_extradata() {
82 validate!(edata.len() >= 36);
83 let mut mr = MemoryReader::new_read(edata.as_slice());
84 let mut br = ByteReader::new(&mut mr);
85 let size = br.read_u32be()? as usize;
86 validate!(size >= 36 && size <= edata.len());
87 let tag = br.read_tag()?;
88 validate!(&tag == b"QDCA");
89 let ver = br.read_u32be()?;
90 validate!(ver == 1);
91 let channels = br.read_u32be()? as usize;
92 validate!(channels == 2 || channels == 1);
93 let srate = br.read_u32be()?;
94 let full_bitrate = br.read_u32be()?;
95 let frame_len = br.read_u32be()? as usize;
96 let packet_size = br.read_u32be()? as usize;
97 validate!(packet_size > 0 && (packet_size & (packet_size - 1)) == 0);
98 validate!(frame_len == packet_size * 16);
99 let bytes_per_frame = br.read_u32be()? as usize;
100 validate!(bytes_per_frame > 6);
101
102 self.order = (31 - (packet_size.leading_zeros() & 31)) as u8;
103 validate!(self.order >= 6 && self.order <= 8);
104 self.frame_bits = self.order + 4;
105 self.samples = frame_len;
106 self.frm_bytes = bytes_per_frame;
107 self.sf_len = packet_size;
108 self.channels = channels;
109
110 let srate = if ainfo.get_sample_rate() != 0 {
111 ainfo.get_sample_rate()
112 } else { srate };
113 self.ainfo = NAAudioInfo::new(srate, channels as u8, SND_S16P_FORMAT, 1);
114 self.chmap = NAChannelMap::from_str(if channels == 1 { "C" } else { "L,R" }).unwrap();
115
116 self.subsampling = self.order - 6;
117 self.fft_part.set_params(channels, self.sf_len, self.subsampling);
118 self.qmf_part.set_ch_and_subsampling(channels, self.subsampling, full_bitrate);
119 } else {
120 return Err(DecoderError::InvalidData);
121 }
122
123 Ok(())
124 } else {
125 Err(DecoderError::InvalidData)
126 }
127 }
128 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
129 let info = pkt.get_stream().get_info();
130 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
131 let pktbuf = pkt.get_buffer();
132 validate!(pktbuf.len() == self.frm_bytes);
133
134 let mut mr = MemoryReader::new_read(pktbuf.as_slice());
135 let mut br = ByteReader::new(&mut mr);
136 let hdr = Packet::read(&mut br)?;
137
138 let (is_intra, has_checksum) = match hdr.id {
139 2 => (true, true),
140 3 => (true, false),
141 4 | 5 => (false, true),
142 6 | 7 => (false, false),
143 _ => return Err(DecoderError::InvalidData),
144 };
145 if has_checksum {
146 let mut csum = u16::from(br.read_byte()?) * 0x101;
147 csum = csum.wrapping_add(u16::from(br.read_byte()?) * 2);
148 for byte in pktbuf.iter() {
149 csum = csum.wrapping_sub(u16::from(*byte));
150 }
151 validate!(csum == 0);
152 }
153 self.fft_part.is_intra = is_intra;
154 self.qmf_part.is_intra = is_intra;
155 self.qmf_part.new_frame();
156
157 let mut tone_pkt_list = Vec::new();
158 let mut fft_pkt_list = Vec::new();
159 while br.left() > 1 {
160 let hdr = Packet::read(&mut br)?;
161 if hdr.id == 0 { break; }
162 match hdr.id {
163 8 => return Err(DecoderError::NotImplemented),
164 9..=12 => {
165 tone_pkt_list.push(hdr);
166 },
167 13 => {
168 let src = &pktbuf[hdr.offset..][..hdr.size];
169 let mut br = QdmBitReader::new(src);
170 self.fft_part.read_type_13(&mut br)?;
171 },
172 14 => {
173 let src = &pktbuf[hdr.offset..][..hdr.size];
174 let mut br = QdmBitReader::new(src);
175 self.fft_part.read_type_14(&mut br)?;
176 },
177 15 => return Err(DecoderError::NotImplemented),
178 16..=23 | 31..=39 | 46..=47 => {
179 fft_pkt_list.push(hdr);
180 },
181 _ => {},
182 };
183 br.read_skip(hdr.size)?;
184 }
185
186 if !tone_pkt_list.is_empty() {
187 let mut has_9 = false;
188 let mut has_10 = false;
189 let mut has_11 = false;
190 let mut pkt_12 = Packet { id: 0, size: 0, offset: 0 };
191 for hdr in tone_pkt_list.iter() {
192 let src = &pktbuf[hdr.offset..][..hdr.size];
193 let mut br = QdmBitReader::new(src);
194 match hdr.id {
195 9 => { self.qmf_part.read_type_9(&mut br)?; has_9 = true; },
196 10 => { self.qmf_part.read_type_10(&mut br)?; has_10 = true; },
197 11 => { self.qmf_part.read_type_11(&mut br)?; has_11 = true; },
198 12 => { pkt_12 = *hdr; },
199 _ => unreachable!(),
200 };
201 }
202 if !has_10 {
203 self.qmf_part.fill_default(10);
204 }
205 if !has_11 {
206 self.qmf_part.fill_default(11);
207 }
208 if pkt_12.id == 12 && has_9 && has_10 {
209 let src = &pktbuf[pkt_12.offset..][..pkt_12.size];
210 let mut br = QdmBitReader::new(src);
211 self.qmf_part.read_type_12(&mut br)?;
212 } else {
213 self.qmf_part.fill_default(12);
214 }
215 self.do_synth = true;
216 }
217
218 if tone_pkt_list.is_empty() && self.do_synth {
219 self.qmf_part.fill_default(10);
220 self.qmf_part.fill_default(11);
221 self.qmf_part.fill_default(12);
222 }
223
224 let channels = self.chmap.num_channels();
225 let abuf = alloc_audio_buffer(self.ainfo, self.samples, self.chmap.clone())?;
226 let mut adata = abuf.get_abuf_i16().unwrap();
227 let off = [adata.get_offset(0), adata.get_offset(1)];
228 let dst = adata.get_data_mut().unwrap();
229
230 self.audio = [[0.0; MAX_FRAME_SIZE]; 2];
231 for subframe in 0..16 {
232 if subframe == 2 {
233 self.fft_part.new_frame();
234 for hdr in fft_pkt_list.iter() {
235 let src = &pktbuf[hdr.offset..][..hdr.size];
236 let mut br = QdmBitReader::new(src);
237 self.fft_part.read_fft_packet(hdr.id, &mut br)?;
238 }
239 }
240 self.fft_part.generate_tones(subframe);
241 for ch in 0..channels {
242 let output = &mut self.audio[ch][subframe * self.sf_len..][..self.sf_len];
243 self.fft_part.synth(output, ch);
244 if self.do_synth {
245 self.qmf_part.synth(output, subframe, ch);
246 }
247 }
248 }
249 let frame_len = self.sf_len * 16;
250 for ch in 0..channels {
251 for (src, dst) in self.audio[ch].iter().take(frame_len).zip(dst[off[ch]..].iter_mut()) {
252 let samp = *src as i32;
253 if samp > (HARDCLIP_THRESHOLD as i32) {
254 *dst = 0x7FFF;
255 } else if samp > (SOFTCLIP_THRESHOLD as i32) {
256 *dst = self.softclip[(samp as usize) - SOFTCLIP_THRESHOLD];
257 } else if samp > -(SOFTCLIP_THRESHOLD as i32) {
258 *dst = samp as i16;
259 } else if samp > -(HARDCLIP_THRESHOLD as i32) {
260 *dst = -self.softclip[(-samp as usize) - SOFTCLIP_THRESHOLD];
261 } else {
262 *dst = -0x8000;
263 }
264 }
265 }
266
267 let mut frm = NAFrame::new_from_pkt(pkt, info.replace_info(NACodecTypeInfo::Audio(self.ainfo)), abuf);
268 frm.set_duration(Some(self.samples as u64));
269 frm.set_keyframe(false);
270 Ok(frm.into_ref())
271 } else {
272 Err(DecoderError::InvalidData)
273 }
274 }
275 fn flush(&mut self) {
276 self.qmf_part.flush();
277 self.fft_part.flush();
278 }
279}
280
281impl NAOptionHandler for Qdmc2Decoder {
282 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
283 fn set_options(&mut self, _options: &[NAOption]) { }
284 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
285}
286
287pub fn get_decoder() -> Box<dyn NADecoder + Send> {
288 Box::new(Qdmc2Decoder::new())
289}
290
291#[cfg(test)]
292mod test {
293 use nihav_core::codecs::RegisteredDecoders;
294 use nihav_core::demuxers::RegisteredDemuxers;
295 use nihav_codec_support::test::dec_video::*;
296 use crate::qt_register_all_decoders;
297 use nihav_commonfmt::generic_register_all_demuxers;
298 #[test]
299 fn test_qdm2() {
300 let mut dmx_reg = RegisteredDemuxers::new();
301 generic_register_all_demuxers(&mut dmx_reg);
302 let mut dec_reg = RegisteredDecoders::new();
303 qt_register_all_decoders(&mut dec_reg);
304
305 //test_decode_audio("mov", "assets/QT/0-22050HzSweep8kb.mov", None, Some("qdm2"), &dmx_reg, &dec_reg);
306 // sample: https://samples.mplayerhq.hu/A-codecs/QDM2/sweep/0-22050HzSweep10kb.mov
307 test_decoding("mov", "qdesign-music2", "assets/QT/0-22050HzSweep10kb.mov", None, &dmx_reg, &dec_reg,
308 ExpectedTestResult::Decodes);
309 }
310}
311
312pub const TONE_SCALES: [[f32; 64]; 2] = [
313 [
314 0.17677669, 0.42677650, 0.60355347, 0.85355347,
315 1.20710683, 1.68359375, 2.37500000, 3.36718750,
316 4.75000000, 6.73437500, 9.50000000, 13.4687500,
317 19.0000000, 26.9375000, 38.0000000, 53.8750000,
318 76.0000000, 107.750000, 152.000000, 215.500000,
319 304.000000, 431.000000, 608.000000, 862.000000,
320 1216.00000, 1724.00000, 2432.00000, 3448.00000,
321 4864.00000, 6896.00000, 9728.00000, 13792.0000,
322 19456.0000, 27584.0000, 38912.0000, 55168.0000,
323 77824.0000, 110336.000, 155648.000, 220672.000,
324 311296.000, 441344.000, 622592.000, 882688.000,
325 1245184.00, 1765376.00, 2490368.00, 0.00000000,
326 0.00000000, 0.00000000, 0.00000000, 0.00000000,
327 0.00000000, 0.00000000, 0.00000000, 0.00000000,
328 0.00000000, 0.00000000, 0.00000000, 0.00000000,
329 0.00000000, 0.00000000, 0.00000000, 0.00000000
330 ], [
331 0.59375000, 0.84179688, 1.18750000, 1.68359375,
332 2.37500000, 3.36718750, 4.75000000, 6.73437500,
333 9.50000000, 13.4687500, 19.0000000, 26.9375000,
334 38.0000000, 53.8750000, 76.0000000, 107.750000,
335 152.000000, 215.500000, 304.000000, 431.000000,
336 608.000000, 862.000000, 1216.00000, 1724.00000,
337 2432.00000, 3448.00000, 4864.00000, 6896.00000,
338 9728.00000, 13792.0000, 19456.0000, 27584.0000,
339 38912.0000, 55168.0000, 77824.0000, 110336.000,
340 155648.000, 220672.000, 311296.000, 441344.000,
341 622592.000, 882688.000, 1245184.00, 1765376.00,
342 2490368.00, 3530752.00, 0.00000000, 0.00000000,
343 0.00000000, 0.00000000, 0.00000000, 0.00000000,
344 0.00000000, 0.00000000, 0.00000000, 0.00000000,
345 0.00000000, 0.00000000, 0.00000000, 0.00000000,
346 0.00000000, 0.00000000, 0.00000000, 0.00000000
347 ]
348];