fix clippy warnings
[nihav.git] / nihav-realmedia / src / muxers / rmvb / audiostream.rs
CommitLineData
9dc1fb4b
KS
1use nihav_core::frame::*;
2use nihav_core::muxers::*;
3use super::RMStreamWriter;
4
5// fourcc, codec name, interleaver, version
6static AUDIO_CODEC_REGISTRY: &[(&[u8;4], &str, &[u8;4], u8)] = &[
7 (b"lpcJ", "ra14.4", b"Int0", 3),
8 (b"28_8", "ra28.8", b"Int4", 4),
9 (b"cook", "cook", b"genr", 5),
10 (b"dnet", "ac3", b"Int0", 4),
11 (b"sipr", "sipro", b"sipr", 4),
12 (b"atrc", "atrac3", b"genr", 5),
13 (b"LSD:", "ralf", b"Int0", 6),
14 (b"raac", "aac", b"vbrs", 5),
15 (b"racp", "aac", b"vbrf", 5),
16];
17
18struct InterleaveParams {
f62e2ae0
KS
19 sample_rate: u32,
20 channels: u8,
9dc1fb4b
KS
21 block_size: usize,
22 factor: usize,
23 frames_per_blk: usize,
24}
25
26trait Interleaver {
27 fn get_flavor(&self) -> usize;
28 fn get_block_size(&self) -> usize;
29 fn get_factor(&self) -> usize;
30 fn get_frames_per_block(&self) -> usize;
c5963b17 31 fn is_empty(&self) -> bool;
9dc1fb4b
KS
32 fn add_packet(&mut self, src: &[u8]) -> bool;
33 fn get_packet(&mut self) -> Option<(Vec<u8>, bool)>;
34 fn flush(&mut self);
35
36 fn get_frame_size(&self) -> usize { self.get_block_size() / self.get_frames_per_block() }
37}
38
39struct NoInterleaver {
40 frame_size: usize,
41 pkt: Option<Vec<u8>>,
42}
43impl Interleaver for NoInterleaver {
44 fn get_flavor(&self) -> usize { 0 }
45 fn get_block_size(&self) -> usize { self.frame_size }
46 fn get_factor(&self) -> usize { 1 }
47 fn get_frames_per_block(&self) -> usize { 1 }
c5963b17 48 fn is_empty(&self) -> bool { self.pkt.is_none() }
9dc1fb4b
KS
49 fn add_packet(&mut self, src: &[u8]) -> bool {
50 if self.pkt.is_none() {
51 self.pkt = Some(src.to_vec());
52 true
53 } else {
54 false
55 }
56 }
57 fn get_packet(&mut self) -> Option<(Vec<u8>, bool)> {
58 let mut ret = None;
59 std::mem::swap(&mut self.pkt, &mut ret);
e6aaad5c 60 ret.map(|pkt| (pkt, true))
9dc1fb4b
KS
61 }
62 fn flush(&mut self) {}
63}
64
65struct Int4Interleaver {
66 flavor: usize,
67 factor: usize,
68 frame_size: usize,
69 block_size: usize,
70 fpb: usize,
71 cur_frame: usize,
72 rd_block: usize,
73 buf: Vec<u8>,
74 map: Vec<usize>,
75}
76impl Int4Interleaver {
77 fn new(frame_size: usize) -> MuxerResult<Self> {
78 let params = RA_28_8_INTERLEAVE_PARAMS;
79 for (flavor, entry) in params.iter().enumerate() {
80 if entry.block_size / entry.frames_per_blk == frame_size {
81 let full_size = entry.frames_per_blk * entry.factor;
82 let mut map = vec![0; full_size];
83 for i in 0..full_size {
84 let fval = i * entry.factor;
85 let mapped = (fval % full_size) + fval / full_size;
86 map[mapped] = i;
87 }
88
89 return Ok(Self {
90 flavor,
91 frame_size,
92 map,
93 factor: entry.factor,
94 block_size: entry.block_size,
95 fpb: entry.frames_per_blk,
96 cur_frame: 0,
97 rd_block: 0,
98 buf: vec![0; entry.block_size * entry.factor],
99 });
100 }
101 }
102 Err(MuxerError::UnsupportedFormat)
103 }
104}
105impl Interleaver for Int4Interleaver {
106 fn get_flavor(&self) -> usize { self.flavor }
107 fn get_block_size(&self) -> usize { self.block_size }
108 fn get_factor(&self) -> usize { self.factor }
109 fn get_frames_per_block(&self) -> usize { self.fpb }
c5963b17 110 fn is_empty(&self) -> bool { self.cur_frame == 0 }
9dc1fb4b
KS
111 fn add_packet(&mut self, src: &[u8]) -> bool {
112 if self.cur_frame == self.factor * self.fpb {
113 return false;
114 }
115 let pos = self.map[self.cur_frame];
e6aaad5c 116 self.buf[pos * self.frame_size..][..self.frame_size].copy_from_slice(src);
9dc1fb4b
KS
117 self.cur_frame += 1;
118 true
119 }
120 fn get_packet(&mut self) -> Option<(Vec<u8>, bool)> {
121 if self.cur_frame == self.factor * self.fpb {
122 let first = self.rd_block == 0;
123 let src = &self.buf[self.rd_block * self.block_size..][..self.block_size];
124 self.rd_block += 1;
125 if self.rd_block == self.factor {
126 self.rd_block = 0;
127 self.cur_frame = 0;
128 }
129 Some((src.to_vec(), first))
130 } else {
131 None
132 }
133 }
134 fn flush(&mut self) {
135 if self.cur_frame != 0 {
136 self.cur_frame = self.factor * self.fpb;
137 }
138 }
139}
140
141struct GenericInterleaver {
142 flavor: usize,
143 factor: usize,
144 frame_size: usize,
145 block_size: usize,
146 fpb: usize,
147 cur_frame: usize,
148 rd_block: usize,
149 buf: Vec<u8>,
150 map: Vec<usize>,
151}
152impl GenericInterleaver {
f62e2ae0 153 fn new(ainfo: NAAudioInfo, frame_size: usize, fcc: [u8; 4]) -> MuxerResult<Self> {
9dc1fb4b
KS
154 let params = match &fcc {
155 b"atrc" => ATRAC_INTERLEAVE_PARAMS,
156 b"cook" => COOK_INTERLEAVE_PARAMS,
157 b"sipr" => SIPRO_INTERLEAVE_PARAMS,
158 _ => return Err(MuxerError::UnsupportedFormat),
159 };
160 for (flavor, entry) in params.iter().enumerate() {
f62e2ae0
KS
161 if entry.sample_rate != 0 && entry.sample_rate != ainfo.sample_rate {
162 continue;
163 }
164 if entry.channels != 0 && entry.channels != ainfo.channels {
165 continue;
166 }
9dc1fb4b
KS
167 if entry.block_size / entry.frames_per_blk == frame_size {
168 let full_size = entry.frames_per_blk * entry.factor;
169 let mut map = vec![0; full_size];
170
171 let mut frm = 0;
172 let mut blk = 0;
173 let mut even = true;
174 for dst in map.iter_mut() {
175 let mapped = blk * entry.frames_per_blk + frm;
176 blk += 2;
177 if blk >= entry.factor {
178 if even {
179 blk = 1;
180 } else {
181 blk = 0;
182 frm += 1;
183 }
184 even = !even;
185 }
186 *dst = mapped;
187 }
188
189 return Ok(Self {
190 flavor,
191 frame_size,
192 map,
193 factor: entry.factor,
194 block_size: entry.block_size,
195 fpb: entry.frames_per_blk,
196 cur_frame: 0,
197 rd_block: 0,
198 buf: vec![0; entry.block_size * entry.factor],
199 });
200 }
201 }
202 Err(MuxerError::UnsupportedFormat)
203 }
204}
205impl Interleaver for GenericInterleaver {
206 fn get_flavor(&self) -> usize { self.flavor }
207 fn get_block_size(&self) -> usize { self.block_size }
208 fn get_factor(&self) -> usize { self.factor }
209 fn get_frames_per_block(&self) -> usize { self.fpb }
c5963b17 210 fn is_empty(&self) -> bool { self.cur_frame == 0 }
9dc1fb4b
KS
211 fn add_packet(&mut self, src: &[u8]) -> bool {
212 if self.cur_frame == self.factor * self.fpb {
213 return false;
214 }
215 let pos = self.map[self.cur_frame];
e6aaad5c 216 self.buf[pos * self.frame_size..][..self.frame_size].copy_from_slice(src);
9dc1fb4b
KS
217 self.cur_frame += 1;
218 true
219 }
220 fn get_packet(&mut self) -> Option<(Vec<u8>, bool)> {
221 if self.cur_frame == self.factor * self.fpb {
222 let first = self.rd_block == 0;
223 let src = &self.buf[self.rd_block * self.block_size..][..self.block_size];
224 self.rd_block += 1;
225 if self.rd_block == self.factor {
226 self.rd_block = 0;
227 self.cur_frame = 0;
228 }
229 Some((src.to_vec(), first))
230 } else {
231 None
232 }
233 }
234 fn flush(&mut self) {
235 if self.cur_frame != 0 {
236 self.cur_frame = self.factor * self.fpb;
237 }
238 }
239}
240
241struct SiproInterleaver {
242 block_size: usize,
243 factor: usize,
244 flavor: usize,
245 buf: Vec<u8>,
246 wr_pos: usize,
247 rd_pos: usize,
248}
249impl SiproInterleaver {
250 fn new(mut frame_size: usize) -> MuxerResult<Self> {
251 if frame_size == 0 {
252 return Err(MuxerError::UnsupportedFormat);
253 }
254 while frame_size < 200 {
255 frame_size <<= 1;
256 }
257 for (flavor, entry) in SIPRO_INTERLEAVE_PARAMS.iter().enumerate() {
258 if entry.block_size == frame_size {
259 return Ok(Self {
260 block_size: entry.block_size,
261 factor: entry.factor,
262 flavor,
263 buf: vec![0; entry.block_size * entry.factor],
264 wr_pos: 0,
265 rd_pos: 0,
266 });
267 }
268 }
269 Err(MuxerError::UnsupportedFormat)
270 }
271}
272impl Interleaver for SiproInterleaver {
273 fn get_flavor(&self) -> usize { self.flavor }
274 fn get_block_size(&self) -> usize { self.block_size }
275 fn get_factor(&self) -> usize { self.factor }
276 fn get_frames_per_block(&self) -> usize { 1 }
c5963b17 277 fn is_empty(&self) -> bool { self.wr_pos == 0 }
9dc1fb4b
KS
278 fn add_packet(&mut self, src: &[u8]) -> bool {
279 if self.wr_pos < self.factor {
280 self.buf[self.wr_pos * self.block_size..][..self.block_size].copy_from_slice(src);
281 self.wr_pos += 1;
282 true
283 } else {
284 false
285 }
286 }
287 fn get_packet(&mut self) -> Option<(Vec<u8>, bool)> {
288 if self.wr_pos == self.factor {
289 let first = self.rd_pos == 0;
290 if self.rd_pos == 0 {
291 sipro_scramble(&mut self.buf, self.factor, self.block_size);
292 }
293 let ret = self.buf[self.rd_pos * self.block_size..][..self.block_size].to_vec();
294 self.rd_pos += 1;
295 if self.rd_pos == self.factor {
296 self.rd_pos = 0;
297 self.wr_pos = 0;
298 }
299 Some((ret, first))
300 } else {
301 None
302 }
303 }
304 fn flush(&mut self) {
305 if self.wr_pos != self.factor {
306 self.wr_pos = self.factor;
307 }
308 }
309}
310
311fn sipro_scramble(buf: &mut [u8], factor: usize, fsize: usize) {
312 let stride = factor * fsize * 2 / 96;
313 for &swap_pair in SIPRO_SWAPS.iter() {
314 let mut sidx = usize::from(swap_pair[0]) * stride;
315 let mut didx = usize::from(swap_pair[1]) * stride;
316 for _ in 0..stride {
317 let in0 = buf[sidx >> 1];
318 let in1 = buf[didx >> 1];
319 let nib0 = (in0 >> ((sidx & 1) * 4)) & 0xF;
320 let nib1 = (in1 >> ((didx & 1) * 4)) & 0xF;
321
322 buf[didx >> 1] = (nib0 << (4 * (didx & 1))) | (in1 & (0xF << (4 * (!didx & 1))));
323 buf[sidx >> 1] = (nib1 << (4 * (sidx & 1))) | (in0 & (0xF << (4 * (!sidx & 1))));
324
325 sidx += 1;
326 didx += 1;
327 }
328 }
329}
330
331struct AACInterleaver {
332 frame_size: usize,
333 data: Vec<u8>,
334 sizes: Vec<usize>,
335 full: bool,
336}
337impl AACInterleaver {
338 fn new(frame_size: usize) -> Self {
339 Self {
340 frame_size,
341 data: Vec::with_capacity(frame_size * 3 / 2),
342 sizes: Vec::with_capacity((frame_size / 128).max(8)),
343 full: false,
344 }
345 }
346}
347impl Interleaver for AACInterleaver {
348 fn get_flavor(&self) -> usize { 0 }
349 fn get_block_size(&self) -> usize { self.frame_size }
350 fn get_factor(&self) -> usize { 1 }
351 fn get_frames_per_block(&self) -> usize { 1 }
c5963b17 352 fn is_empty(&self) -> bool { self.data.is_empty() }
9dc1fb4b
KS
353 fn add_packet(&mut self, src: &[u8]) -> bool {
354 if !self.full {
355 self.data.extend_from_slice(src);
356 self.sizes.push(src.len());
357 if self.data.len() >= self.frame_size {
358 self.full = true;
359 }
360 true
361 } else {
362 false
363 }
364 }
365 fn get_packet(&mut self) -> Option<(Vec<u8>, bool)> {
366 if self.full {
367 let mut dst = Vec::with_capacity(self.frame_size);
368 let mut gw = GrowableMemoryWriter::new_write(&mut dst);
369 let mut bw = ByteWriter::new(&mut gw);
370 bw.write_u16be((self.sizes.len() * 16) as u16).unwrap();
371 for &pkt_size in self.sizes.iter() {
372 bw.write_u16be(pkt_size as u16).unwrap();
373 }
374 bw.write_buf(&self.data).unwrap();
375
376 self.data.clear();
377 self.sizes.clear();
378 self.full = false;
379
380 Some((dst, true))
381 } else {
382 None
383 }
384 }
385 fn flush(&mut self) {
386 if !self.sizes.is_empty() {
387 self.full = true;
388 }
389 }
390}
391
392struct InterleaveInfo {
393 fcc: [u8; 4],
394 il_fcc: [u8; 4],
395 block_size: usize,
396 frame_size: usize,
397 factor: usize,
398 flavor: usize,
399}
400
401struct AudioStreamWriter {
402 fcc: [u8; 4],
403 il_fcc: [u8; 4],
404 is_raw: bool,
405 version: u8,
406 header_pos: u64,
407 interleave: Box<dyn Interleaver>,
408 data_size: usize,
c5963b17
KS
409 first_time: u32,
410 last_time: u32,
411 size_in: usize,
412 size_out: usize,
9dc1fb4b
KS
413}
414
415impl RMStreamWriter for AudioStreamWriter {
416 fn write_header(&mut self, bw: &mut ByteWriter, astream: &NAStream) -> MuxerResult<()> {
417 self.header_pos = bw.tell();
418 if self.version < 6 {
419 bw.write_buf(b".ra\xFD")?;
420 bw.write_u16be(self.version.into())?;
421 }
422
423 let il_info = InterleaveInfo {
424 fcc: self.fcc,
425 il_fcc: self.il_fcc,
426 block_size: self.interleave.get_block_size(),
427 frame_size: self.interleave.get_frame_size(),
428 factor: self.interleave.get_factor(),
429 flavor: self.interleave.get_flavor(),
430 };
431
432 match self.version {
433 3 => write_aformat3(bw, astream, &il_info)?,
434 4 => write_aformat4(bw, astream, &il_info)?,
435 5 => write_aformat5(bw, astream, &il_info)?,
436 6 => write_lsd(bw, astream)?,
437 _ => unreachable!(),
438 }
439 Ok(())
440 }
c5963b17 441 fn queue_packet(&mut self, pkt: NAPacket, ms: u32) -> bool {
9dc1fb4b
KS
442 let src = pkt.get_buffer();
443 self.data_size += src.len();
444 let frame_size = self.interleave.get_frame_size();
c5963b17
KS
445 self.last_time = ms;
446 if self.interleave.is_empty() {
447 self.first_time = ms;
448 self.size_in = 0;
449 self.size_out = 0;
450 } else {
451 self.size_in += src.len() / frame_size;
452 }
9dc1fb4b
KS
453 if !self.is_raw {
454 let mut ret = false;
455 for frame in src.chunks(frame_size) {
456 ret = self.interleave.add_packet(frame);
457 }
458 ret
459 } else {
460 self.interleave.add_packet(&src)
461 }
462 }
c5963b17
KS
463 fn get_packet(&mut self) -> Option<(Vec<u8>, u32, bool)> {
464 if let Some((pkt, first)) = self.interleave.get_packet() {
465 let time_add = if self.last_time > self.first_time && self.size_in > 0 {
466 let size = pkt.len();
467 let time_add = (self.size_out * ((self.last_time - self.first_time) as usize) / self.size_in) as u32;
468 self.size_out += size / self.interleave.get_frame_size();
469 time_add
470 } else {
471 0
472 };
473 Some((pkt, self.first_time + time_add, first))
474 } else {
475 None
476 }
477 }
9dc1fb4b
KS
478 fn flush(&mut self) { self.interleave.flush() }
479 fn finish(&mut self, bw: &mut ByteWriter) -> MuxerResult<()> {
480 let cur_pos = bw.tell();
481 match self.version {
482 3 => {
483 bw.seek(SeekFrom::Start(self.header_pos + 18))?;
484 bw.write_u32be(self.data_size as u32)?;
485 },
486 4 | 5 => {
487 bw.seek(SeekFrom::Start(self.header_pos + 12))?;
488 bw.write_u32be(self.data_size/*+header_size*/ as u32)?;
489 bw.seek(SeekFrom::Current(12))?;
490 bw.write_u32be(self.data_size as u32)?;
491 },
492 6 => unimplemented!(),
493 _ => unreachable!(),
494 };
495 bw.seek(SeekFrom::Start(cur_pos))?;
496 Ok(())
497 }
353373a3 498 fn set_pkt_size(&mut self, _pkt_size: usize) {}
9dc1fb4b
KS
499}
500
501fn write_audio_metadata(bw: &mut ByteWriter) -> MuxerResult<()> {
502 bw.write_byte(0)?; // title_string_length
503 bw.write_byte(0)?; // author_string_length
504 bw.write_byte(0)?; // copyright_string_length
505 bw.write_byte(0)?; // user_string_length
506 Ok(())
507}
508
509fn write_aformat3(bw: &mut ByteWriter, _stream: &NAStream, il_info: &InterleaveInfo) -> MuxerResult<()> {
510 let start = bw.tell();
511 bw.write_u16be(0)?; // header_bytes
512 bw.write_u16be(il_info.flavor as u16)?;
513 bw.write_u32be(il_info.frame_size as u32)?; // granularity
514 bw.write_u32be(0)?; // bytes per minute
515 bw.write_u32be(0)?; // total bytes
516 write_audio_metadata(bw)?;
517 bw.write_byte(0)?; //can_copy
518 bw.write_byte(4)?; // FCC length
519 bw.write_buf(&il_info.fcc)?;
520 let end = bw.tell();
521 bw.seek(SeekFrom::Start(start))?;
522 bw.write_u16be((end - start - 2) as u16)?;
523 bw.seek(SeekFrom::Start(end))?;
524
525 Ok(())
526}
527
528fn write_aformat4(bw: &mut ByteWriter, stream: &NAStream, il_info: &InterleaveInfo) -> MuxerResult<()> {
529 let info = stream.get_info().get_properties().get_audio_info().unwrap();
530
531 bw.write_u16be(0)?;
532 let start = bw.tell();
533 bw.write_buf(b".ra4")?;
534 bw.write_u32be(0)?; // data size
535 bw.write_u16be(4)?; // version
536 bw.write_u16be(0)?; // revision
537 bw.write_u16be(0)?; // header_bytes
538 bw.write_u16be(il_info.flavor as u16)?;
539 bw.write_u32be(il_info.frame_size as u32)?; // granularity
540 bw.write_u32be(0)?; // total bytes
541 bw.write_u32be(0)?; // bytes_per_minute
542 bw.write_u32be(0)?; // bytes_per_minute2
543 bw.write_u16be(il_info.factor as u16)?;
544 bw.write_u16be(il_info.block_size as u16)?;
545 bw.write_u16be(0)?; // user data
546 bw.write_u32be(info.sample_rate)?; // sample rate
547 bw.write_u32be(info.format.bits.into())?; // sample size
548 bw.write_u16be(info.channels.into())?; // num channels
549 bw.write_byte(4)?; // ileave ID len
550 bw.write_buf(&il_info.il_fcc)?;
551 bw.write_byte(4)?; // codec ID len
552 bw.write_buf(&il_info.fcc)?;
553 bw.write_byte(if &il_info.il_fcc == b"Int0" { 0 } else { 1 })?;
554 bw.write_byte(7)?; // can_copy
555 bw.write_byte(0)?; // stream_type
556 write_audio_metadata(bw)?;
557 let end = bw.tell();
558 bw.seek(SeekFrom::Start(start + 12))?;
559 bw.write_u16be((end - start - 4) as u16)?;
560 bw.seek(SeekFrom::Start(end))?;
561
562 Ok(())
563}
564
565fn write_aformat5(bw: &mut ByteWriter, stream: &NAStream, il_info: &InterleaveInfo) -> MuxerResult<()> {
566 let info = stream.get_info().get_properties().get_audio_info().unwrap();
567
568 bw.write_u16be(0)?;
569 let start = bw.tell();
570 bw.write_buf(b".ra5")?;
571 bw.write_u32be(0)?; // data size
572 bw.write_u16be(5)?; // version
573 bw.write_u16be(0)?; // revision
574 bw.write_u16be(0)?; // header_bytes
575 bw.write_u16be(il_info.flavor as u16)?;
576 bw.write_u32be(il_info.block_size as u32)?; // granularity
577 bw.write_u32be(0)?; // total bytes
578 bw.write_u32be(0)?; // bytes_per_minute
579 bw.write_u32be(0)?; // bytes_per_minute2
580 bw.write_u16be(il_info.factor as u16)?;
581 bw.write_u16be(il_info.block_size as u16)?;
582 bw.write_u16be(il_info.frame_size as u16)?;
583 bw.write_u16be(0)?; // user data
584 bw.write_u32be(info.sample_rate)?; // sample rate
585 bw.write_u32be(info.sample_rate)?; // actual sample rate
586 bw.write_u32be(info.format.bits.into())?; // sample size
587 bw.write_u16be(info.channels.into())?; // num channels
588 bw.write_buf(&il_info.il_fcc)?;
589 bw.write_buf(&il_info.fcc)?;
590 bw.write_byte(if &il_info.il_fcc == b"Int0" { 0 } else { 1 })?;
591 bw.write_byte(7)?; // can_copy
592 bw.write_byte(0)?; // stream_type
593 bw.write_byte(0)?; // has_interleave_pattern
594 if let Some(edata) = stream.get_info().get_extradata() {
595 if !matches!(&il_info.fcc, b"raac" | b"racp") {
596 bw.write_u32be(edata.len() as u32)?;
597 bw.write_buf(&edata)?;
598 } else {
599 bw.write_u32be((edata.len() + 1) as u32)?;
600 bw.write_byte(2)?;
601 bw.write_buf(&edata)?;
602 }
603 } else {
604 bw.write_u32be(0)?;
605 }
606 let end = bw.tell();
607 bw.seek(SeekFrom::Start(start + 12))?;
608 bw.write_u16be((end - start - 4) as u16)?;
609 bw.seek(SeekFrom::Start(end))?;
610
611 Ok(())
612}
613
614fn write_lsd(bw: &mut ByteWriter, stream: &NAStream) -> MuxerResult<()> {
615 if let Some(edata) = stream.get_info().get_extradata() {
616 bw.write_buf(&edata)?;
617 }
618 Ok(())
619}
620
621fn create_interleaver(id: [u8; 4], fcc: [u8; 4], ainfo: NAAudioInfo) -> MuxerResult<Box<dyn Interleaver>> {
622 let frame_size = ainfo.block_len;
623 match &id {
624 b"Int0" => Ok(Box::new(NoInterleaver{ frame_size, pkt: None })),
625 b"Int4" => Ok(Box::new(Int4Interleaver::new(frame_size)?)),
626 b"sipr" => Ok(Box::new(SiproInterleaver::new(frame_size)?)),
f62e2ae0 627 b"genr" => Ok(Box::new(GenericInterleaver::new(ainfo, frame_size, fcc)?)),
9dc1fb4b
KS
628 b"vbrs" | b"vbrf" => Ok(Box::new(AACInterleaver::new(1024))),
629 _ => unimplemented!(),
630 }
631}
632
633pub fn create_audio_stream(stream: &NAStream) -> MuxerResult<Box<dyn RMStreamWriter>> {
634 let info = stream.get_info();
635 let cname = info.get_name();
636 let mut fourcc = [0u8; 4];
637 let mut ileave = [0u8; 4];
638 let mut version = 0;
639 for &(fcc, name, ileaver, cversion) in AUDIO_CODEC_REGISTRY.iter() {
640 if name == cname {
641 fourcc = *fcc;
642 ileave = *ileaver;
643 version = cversion;
644 break;
645 }
646 }
647 if version > 0 {
648 let ainfo = info.get_properties().get_audio_info().unwrap();
649 Ok(Box::new(AudioStreamWriter {
650 fcc: fourcc,
651 il_fcc: ileave,
652 is_raw: &ileave == b"Int0",
653 version,
654 interleave: create_interleaver(ileave, fourcc, ainfo)?,
655 header_pos: 0,
656 data_size: 0,
c5963b17
KS
657 first_time: 0,
658 last_time: 0,
659 size_in: 0,
660 size_out: 0,
9dc1fb4b
KS
661 }))
662 } else {
663 Err(MuxerError::UnsupportedFormat)
664 }
665}
666
667const SIPRO_SWAPS: [[u8; 2]; 38] = [
668 [ 0, 63 ], [ 1, 22 ], [ 2, 44 ], [ 3, 90 ],
669 [ 5, 81 ], [ 7, 31 ], [ 8, 86 ], [ 9, 58 ],
670 [ 10, 36 ], [ 12, 68 ], [ 13, 39 ], [ 14, 73 ],
671 [ 15, 53 ], [ 16, 69 ], [ 17, 57 ], [ 19, 88 ],
672 [ 20, 34 ], [ 21, 71 ], [ 24, 46 ], [ 25, 94 ],
673 [ 26, 54 ], [ 28, 75 ], [ 29, 50 ], [ 32, 70 ],
674 [ 33, 92 ], [ 35, 74 ], [ 38, 85 ], [ 40, 56 ],
675 [ 42, 87 ], [ 43, 65 ], [ 45, 59 ], [ 48, 79 ],
676 [ 49, 93 ], [ 51, 89 ], [ 55, 95 ], [ 61, 76 ],
677 [ 67, 83 ], [ 77, 80 ]
678];
679
f62e2ae0
KS
680macro_rules! int_params {
681 ($rate:expr, $ch:expr, $bsize:expr, $factor:expr, $frm_per_blk:expr) => {
682 InterleaveParams {
683 sample_rate: $rate,
684 channels: $ch,
685 block_size: $bsize,
686 factor: $factor,
687 frames_per_blk: $frm_per_blk,
688 }
689 }
690}
691
9dc1fb4b 692const RA_28_8_INTERLEAVE_PARAMS: &[InterleaveParams] = &[
f62e2ae0 693 int_params!(0, 1, 228, 12, 6)
9dc1fb4b 694];
f62e2ae0
KS
695const SIPRO_INTERLEAVE_PARAMS: &[InterleaveParams] = &[ //2,1,3,0
696 int_params!( 8000, 1, 232, 6, 16),
697 int_params!( 8000, 1, 304, 6, 16),
698 int_params!( 8000, 1, 296, 6, 16),
699 int_params!(16000, 1, 320, 6, 16),
9dc1fb4b
KS
700];
701const ATRAC_INTERLEAVE_PARAMS: &[InterleaveParams] = &[
f62e2ae0
KS
702 int_params!(0, 0, 768, 20, 4),
703 int_params!(0, 0, 1088, 20, 4),
704 int_params!(0, 0, 912, 30, 3),
705 int_params!(0, 0, 1152, 30, 3),
706 int_params!(0, 0, 1272, 30, 3),
707 int_params!(0, 0, 1024, 30, 2),
708 int_params!(0, 0, 768, 10, 1),
709 int_params!(0, 0, 1024, 10, 1),
9dc1fb4b
KS
710];
711const COOK_INTERLEAVE_PARAMS: &[InterleaveParams] = &[
f62e2ae0
KS
712 int_params!( 8000, 1, 288, 8, 9),
713 int_params!(11025, 1, 352, 8, 11),
714 int_params!(22050, 1, 564, 8, 12),
715 int_params!(22050, 1, 600, 9, 10),
716 int_params!(44100, 1, 651, 14, 7),
717 int_params!(44100, 1, 640, 15, 5),
718 int_params!(44100, 1, 744, 20, 4),
719 int_params!(22050, 1, 558, 16, 6),
720 int_params!( 8000, 1, 288, 6, 12),
721 int_params!(11025, 2, 580, 10, 10),
722 int_params!(22050, 2, 564, 14, 6),
723 int_params!(22050, 2, 640, 16, 5),
724 int_params!(44100, 2, 744, 20, 4),
725 int_params!(44100, 2, 834, 30, 3),
726 int_params!(44100, 1, 644, 20, 4),
727 int_params!(44100, 1, 600, 9, 10),
728 int_params!(44100, 1, 651, 14, 7),
729 int_params!(22050, 2, 528, 10, 10),
730 int_params!(22050, 2, 600, 10, 10),
731 int_params!(22050, 2, 600, 10, 10),
732 int_params!(22050, 2, 465, 16, 5),
733 int_params!(44100, 2, 465, 16, 5),
734 int_params!(44100, 2, 640, 16, 5),
735 int_params!(44100, 2, 640, 16, 5),
736 int_params!(44100, 2, 930, 16, 5),
737 int_params!(44100, 2, 1400, 16, 5),
738 int_params!(11025, 2, 376, 8, 11),
739 int_params!(44100, 2, 930, 16, 5),
740 int_params!(44100, 2, 1400, 16, 5),
741 int_params!(22050, 2, 640, 16, 5),
742 int_params!(44100, 5, 1395, 16, 5),
743 int_params!(44100, 6, 1143, 10, 3),
744 int_params!(44100, 6, 1064, 10, 2),
745 int_params!(44100, 6, 778, 1, 1),
9dc1fb4b 746];