use broadcast_common::{Parse, Serialize};
use rdd29::{
AnyElement, AtmosFrame, AudioDataDlc, BedChannel, BedDefinition1, BitDepth, ChannelId,
FrameRate, SampleRate,
};
fn real_eac3_frame() -> Vec<u8> {
std::fs::read(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/fixtures/eac3_frame0.bin"
))
.expect("eac3_frame0.bin fixture must exist")
}
fn build_frame(payload: &[u8]) -> AtmosFrame<'_> {
let bed = BedDefinition1::new(
1,
vec![BedChannel {
channel_id: ChannelId::LeftScreen,
audio_data_id: 10,
}],
);
let dlc = AudioDataDlc::new(10, payload).expect("build AudioDataDLC from real E-AC-3 frame");
AtmosFrame::new(
SampleRate::Hz48000,
BitDepth::Bits24,
FrameRate::Fps24,
1,
vec![
AnyElement::BedDefinition1(bed),
AnyElement::AudioDataDlc(dlc),
],
)
}
#[test]
fn wraps_real_eac3_frame_and_parses_back() {
let payload = real_eac3_frame();
assert_eq!(
payload.len(),
834,
"real E-AC-3 frame 0 is 834 bytes (ffprobe-confirmed, see st337/docs/st337-PROVENANCE.md)"
);
let frame = build_frame(&payload);
let bytes = frame.to_bytes();
let parsed = AtmosFrame::parse(&bytes).expect("parse the wrapped real frame");
assert_eq!(parsed.elements.len(), 2);
let AnyElement::AudioDataDlc(dlc) = &parsed.elements[1] else {
panic!("expected AudioDataDLC as the second element");
};
assert_eq!(dlc.audio_data_id, 10);
assert_eq!(
dlc.payload, payload,
"payload extracted from the parsed AudioDataDLC must be byte-identical to the real \
E-AC-3 frame"
);
}
#[test]
fn byte_identical_round_trip_real_fixture() {
let payload = real_eac3_frame();
let frame = build_frame(&payload);
let mut out = vec![0u8; frame.serialized_len()];
let n = frame.serialize_into(&mut out).unwrap();
assert_eq!(n, out.len());
let reparsed = AtmosFrame::parse(&out).unwrap();
assert_eq!(reparsed, frame, "parse(serialize(frame)) == frame");
let mut out2 = vec![0u8; reparsed.serialized_len()];
reparsed.serialize_into(&mut out2).unwrap();
assert_eq!(
out, out2,
"serialize(parse(serialize(frame))) is byte-identical"
);
}
#[test]
fn mutating_meta_id_changes_only_bed_definition_bytes() {
let payload = real_eac3_frame();
let mut frame = build_frame(&payload);
let original = frame.to_bytes();
let AnyElement::BedDefinition1(bed) = &mut frame.elements[0] else {
panic!("expected BedDefinition1 as the first element");
};
bed.meta_id = 200;
let mutated = frame.to_bytes();
assert_ne!(
original, mutated,
"changing meta_id must change the wire bytes"
);
assert_eq!(
&original[original.len() - payload.len()..],
&mutated[mutated.len() - payload.len()..],
"the real E-AC-3 payload bytes themselves must be untouched"
);
}