Skip to main content

Crate st337

Crate st337 

Source
Expand description

SMPTE ST 337:2015 non-PCM audio/data burst-preamble framing over AES3.

This crate implements exactly the wire structures described in the curated spec transcription at st337/docs/st337.md (fetched directly from https://pub.smpte.org/latest/st337/st0337-2015.pdf) — cite that file, not this doc comment, as the field-semantics oracle. See also st337/docs/st337-PROVENANCE.md for a real-fixture / independent-oracle (ffmpeg -f spdif) cross-check of the constants and bit layout below.

  • Burst — one complete non-PCM data burst: BurstPreamble (Pa.. Pd, or Pa..Pf for the “extended” six-word form) followed by the opaque burst_payload bytes (§7.1/§7.2).
  • DataMode — the data_mode field (§7.2.4.3 Table 8): this crate supports only DataMode::Mode16 for parsing/building (see the “Scope decisions” section of docs/st337.md).

What this crate is not: an AES3 physical-layer (biphase-mark line code, subframe/timeslot bit placement) codec. It parses/builds the logical burst-preamble/burst-payload word sequence as a plain byte stream (&[u8], 2 bytes per 16-bit preamble word) — the same “parse the container, not the physical/codec layer” discipline this workspace’s transmux crate uses for media containers. It also does not define a data_type -> codec enum: that mapping is registered in the companion spec SMPTE ST 338, which was not available to verify truthfully (see docs/st337.md).

Depends only on broadcast-common. #![no_std] (+ alloc) when the std feature is disabled.

§Examples

Build a burst from a payload and round-trip it:

use broadcast_common::{Parse, Serialize};
use st337::{Burst, DataMode};

let payload = [0xDE, 0xAD, 0xBE, 0xEF];
let burst = Burst::new(1, DataMode::Mode16, false, 0, 0, None, &payload).unwrap();

let mut bytes = vec![0u8; burst.serialized_len()];
burst.serialize_into(&mut bytes).unwrap();
assert_eq!(Burst::parse(&bytes).unwrap(), burst);

§Runnable examples

Run with cargo run -p st337 --example <name>.

§build_burst

//! Build an ST 337 burst from typed preamble fields + a payload, and
//! serialize it to wire bytes — SMPTE ST 337:2015 §7.
//!
//! Run with `cargo run -p st337 --example build_burst`.

use broadcast_common::Serialize;
use st337::{Burst, DataMode};

fn main() {
    // A minimal four-word-preamble burst carrying an arbitrary payload.
    // `data_type` 1 is used here purely as an example value (this crate does
    // not define a data_type -> codec mapping -- see docs/st337.md).
    let payload = b"example non-PCM burst payload bytes";
    let burst = Burst::new(
        1,                // data_type
        DataMode::Mode16, // data_mode -- the only mode this crate supports
        false,            // error_flag
        0,                // data_type_dependent
        0,                // data_stream_number (0 = main audio service)
        None,             // extended (Pe/Pf) -- only used when data_type == 31
        payload,
    )
    .expect("build burst");

    let mut bytes = vec![0u8; burst.serialized_len()];
    burst.serialize_into(&mut bytes).expect("serialize");

    println!("serialized {} bytes:", bytes.len());
    println!(
        "{}",
        bytes
            .iter()
            .map(|b| format!("{b:02x}"))
            .collect::<Vec<_>>()
            .join(" ")
    );
    println!(
        "Pa={:#06x} Pb={:#06x} length_code={} bits",
        u16::from_le_bytes([bytes[0], bytes[1]]),
        u16::from_le_bytes([bytes[2], bytes[3]]),
        burst.preamble.length_code
    );
}

§parse_burst

//! Wrap the committed real-fixture E-AC-3 frame (`tests/fixtures/eac3_frame0.bin`)
//! in an ST 337 burst, parse it back, and confirm the payload is
//! byte-identical to the real capture — SMPTE ST 337:2015 §7.
//!
//! Run with `cargo run -p st337 --example parse_burst`.

use broadcast_common::{Parse, Serialize};
use st337::{Burst, DataMode};

fn main() {
    // See docs/st337-PROVENANCE.md for how this fixture was extracted (a
    // real E-AC-3 syncframe from fixtures/ts/dolby/eac3.ts) and cross-checked
    // against ffmpeg's own IEC 61937 burst framing.
    let path = concat!(
        env!("CARGO_MANIFEST_DIR"),
        "/tests/fixtures/eac3_frame0.bin"
    );
    let payload = std::fs::read(path).expect("fixture must exist");

    let burst = Burst::new(
        21, // data_type -- the IEC 61937 E-AC-3 code point used by the real
        // ffmpeg cross-check oracle (docs/st337-PROVENANCE.md); ST 337 itself
        // defers the data_type registry to SMPTE ST 338 (not verified here).
        DataMode::Mode16,
        false,
        0,
        0,
        None,
        &payload,
    )
    .expect("build burst");
    let bytes = burst.to_bytes();

    let parsed = Burst::parse(&bytes).expect("parse burst");
    println!("data_type: {}", parsed.preamble.data_type);
    println!("data_mode: {}", parsed.preamble.data_mode);
    println!("error_flag: {}", parsed.preamble.error_flag);
    println!("data_stream_number: {}", parsed.preamble.data_stream_number);
    println!(
        "length_code: {} bits ({} payload bytes)",
        parsed.preamble.length_code,
        parsed.payload.len()
    );
    assert_eq!(
        parsed.payload, payload,
        "byte-identical real E-AC-3 payload"
    );
    println!("payload matches the real E-AC-3 fixture byte-for-byte.");
}

Structs§

Burst
One complete non-PCM data burst: BurstPreamble + burst_payload (SMPTE ST 337 §7.1).
BurstPreamble
The burst preamble (Pa..Pd, or Pa..Pf when Self::extended is Some) — SMPTE ST 337 §7.2.
ExtendedPreamble
The six-word preamble’s extra words, Pe and Pf (Table 6, §7.2.1), present only when BurstPreamble::data_type == EXTENDED_DATA_TYPE_MARKER.

Enums§

DataMode
The 2-bit data_mode field (§7.2.4.3 Table 8): which of the 16/20/24-bit AES3-3 subframe positions a burst’s words occupy.
Error
An ST 337 burst parse / serialize error.

Constants§

EXTENDED_DATA_TYPE_MARKER
data_type value reserved to mean “see extended_data_type (Pe)” — the four-word preamble’s data_type field is only 5 bits wide, so 31 is the escape code to the six-word preamble’s 16-bit Pe code space (§7.2.1/§7.2.4.2).
MAX_5_BIT_FIELD
Maximum data_type / data_type_dependent value — both 5-bit fields (Table 7).
MAX_DATA_STREAM_NUMBER
Maximum data_stream_number value — a 3-bit field (Table 7, §7.2.4.6).
MAX_LENGTH_CODE_BITS
Maximum length_code (Pd) value in 16-bit mode: “from 0 to 65,535 bits in the 16-bit mode” (§7.2.5).
SYNC_WORD_PA
Pa — sync word 1, 16-bit mode (Table 6, §7.2.1). Independently confirmed against a real ffmpeg -f spdif burst — see docs/st337-PROVENANCE.md.
SYNC_WORD_PB
Pb — sync word 2, 16-bit mode (Table 6, §7.2.1). Independently confirmed against a real ffmpeg -f spdif burst — see docs/st337-PROVENANCE.md.

Type Aliases§

Result
Result alias for st337 parsing/serialization.