swf_emitter/
sound.rs

1use std::convert::TryInto;
2use std::io;
3
4use swf_types as ast;
5
6use crate::primitives::{emit_le_u16, emit_le_u32, emit_u8};
7
8pub(crate) fn audio_coding_format_to_code(value: ast::AudioCodingFormat) -> u8 {
9  match value {
10    ast::AudioCodingFormat::UncompressedNativeEndian => 0,
11    ast::AudioCodingFormat::Adpcm => 1,
12    ast::AudioCodingFormat::Mp3 => 2,
13    ast::AudioCodingFormat::UncompressedLittleEndian => 3,
14    ast::AudioCodingFormat::Nellymoser16 => 4,
15    ast::AudioCodingFormat::Nellymoser8 => 5,
16    ast::AudioCodingFormat::Nellymoser => 6,
17    ast::AudioCodingFormat::Speex => 11,
18  }
19}
20
21pub(crate) fn sound_rate_to_code(value: ast::SoundRate) -> u8 {
22  match value {
23    ast::SoundRate::SoundRate5500 => 0,
24    ast::SoundRate::SoundRate11000 => 1,
25    ast::SoundRate::SoundRate22000 => 2,
26    ast::SoundRate::SoundRate44000 => 3,
27  }
28}
29
30pub(crate) fn emit_sound_info<W: io::Write>(writer: &mut W, value: &ast::SoundInfo) -> io::Result<()> {
31  let has_in_point = value.in_point.is_some();
32  let has_out_point = value.out_point.is_some();
33  let has_loops = value.loop_count.is_some();
34  let has_envelope = value.envelope_records.is_some();
35  let sync_no_multiple = value.sync_no_multiple;
36  let sync_stop = value.sync_stop;
37
38  #[allow(clippy::identity_op)]
39  let flags: u8 = 0
40    | (if has_in_point { 1 << 0 } else { 0 })
41    | (if has_out_point { 1 << 1 } else { 0 })
42    | (if has_loops { 1 << 2 } else { 0 })
43    | (if has_envelope { 1 << 3 } else { 0 })
44    | (if sync_no_multiple { 1 << 4 } else { 0 })
45    | (if sync_stop { 1 << 5 } else { 0 });
46  // Skip bits [6, 7]
47  emit_u8(writer, flags)?;
48
49  if let Some(in_point) = value.in_point {
50    emit_le_u32(writer, in_point)?;
51  }
52  if let Some(out_point) = value.out_point {
53    emit_le_u32(writer, out_point)?;
54  }
55  if let Some(loop_count) = value.loop_count {
56    emit_le_u16(writer, loop_count)?;
57  }
58  if let Some(ref envelope) = &value.envelope_records {
59    emit_sound_envelope(writer, envelope)?;
60  }
61
62  Ok(())
63}
64
65pub(crate) fn emit_sound_envelope<W: io::Write>(writer: &mut W, value: &[ast::SoundEnvelope]) -> io::Result<()> {
66  emit_u8(writer, value.len().try_into().unwrap())?;
67  for record in value {
68    emit_le_u32(writer, record.pos44)?;
69    emit_le_u16(writer, record.left_level)?;
70    emit_le_u16(writer, record.right_level)?;
71  }
72
73  Ok(())
74}