Skip to content

Add support for AMR-WB - #995

Draft
xnorpx wants to merge 1 commit into
mainfrom
dev/amrwb
Draft

Add support for AMR-WB#995
xnorpx wants to merge 1 commit into
mainfrom
dev/amrwb

Conversation

@xnorpx

@xnorpx xnorpx commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator

Not ready, need more iterations

Architecture / mental model

This change adds an AMR-WB RTP payload adapter, not an AMR-WB encoder or decoder. Applications provide and receive already encoded 3GPP IF frames; str0m negotiates the supported transport profile and converts between IF frames and RFC 4867 RTP payloads.

There are three representations to keep distinct:

  1. SDP representation: CodecSpec and FormatParams describe the negotiated payload shape.
  2. Application representation: 3GPP IF frames, consisting of a one-byte FT/Q header followed by encoded speech bytes.
  3. Network representation: RFC 4867 RTP payloads containing CMR, ToC entries, and speech bits.
flowchart LR
    subgraph Control["Control plane: SDP negotiation"]
        Config["CodecConfig<br/>PT 122, 16 kHz, mono"]
        Params["FormatParam / FormatParams"]
        Gate["AMR-WB compatibility gate"]
        Spec["Negotiated CodecSpec"]

        Config --> Params --> Gate --> Spec
    end

    subgraph Send["Send path"]
        Writer["Writer::write<br/>one 3GPP IF frame + MediaTime"]
        Payloader["Payloader<br/>select negotiated layout"]
        Packetizer["AmrWbPacketizer<br/>IF frame -> RFC 4867 payload"]
        RTPOut["RTP / SRTP"]

        Writer --> Payloader --> Packetizer --> RTPOut
    end

    subgraph Receive["Receive path"]
        RTPIn["RTP / SRTP"]
        Buffer["DepacketizingBuffer"]
        Depacketizer["AmrWbDepacketizer<br/>RFC 4867 -> IF frames"]
        Event["Event::MediaData"]

        RTPIn --> Buffer --> Depacketizer --> Event
    end

    Spec -. configures .-> Payloader
    Spec -. configures .-> Depacketizer
Loading

Control plane

enable_amr_wb(true) adds an opt-in mono codec configuration using dynamic PT 122, a 16 kHz RTP clock, and the common IMS/VoLTE format:

octet-align=1;mode-change-capability=2;max-red=0

The SDP layer parses AMR-WB parameters into typed FormatParams. Compatibility matching then accepts only configurations the packet layer can actually process. Parameters that change the wire format must match and are echoed unchanged in the answer.

Unsupported or malformed configurations are declined rather than negotiated and misdecoded. This includes CRC, interleaving, robust sorting, multiple channels, restricted mode sets, and unsupported mode-change constraints.

Send path

Each Writer::write call must contain exactly one 3GPP IF frame and one media timestamp. AMR-WB frames represent 20 ms, or 320 ticks at 16 kHz, so accepting concatenated frames would make timestamp ownership ambiguous.

The packetizer:

  • validates the IF header, frame type, encoded length, and MTU;
  • rejects reserved frame types, concatenated frames, and standalone NO_DATA;
  • emits exactly one RFC 4867 RTP payload;
  • uses either octet-aligned or bandwidth-efficient packing according to SDP;
  • emits CMR 15, meaning no codec mode request.

The generic RTP layer supplies sequence numbers, the rebased 16 kHz timestamp, extensions, and the talkspurt marker.

Receive path

Incoming RTP is mapped to the negotiated payload type, and the depacketizer is configured from the same octet-align setting as the sender.

Unlike the send API, the receiver accepts valid compound RFC 4867 payloads because remote peers may place multiple ToC entries in one RTP packet. These are returned as concatenated IF frames in Event::MediaData.

The receiver rejects reserved frame types, truncated speech data, unexpected trailing octets, and nonzero terminal padding.

Code map

  • SDP parsing and serialization: data.rs
  • Typed codec parameters: format_params.rs
  • Compatibility and answer shaping: payload_params.rs
  • RFC 4867 conversion: amr_wb.rs
  • Runtime packetizer dispatch: mod.rs
  • Send configuration: payload.rs
  • Receive configuration: mod.rs
  • End-to-end coverage: amr-wb.rs

A useful review order is: SDP compatibility rules → packet conversion → runtime wiring → integration and malformed-input tests.

Comment thread src/format/codec.rs
Opus,
PCMU,
PCMA,
/// AMR Wideband (RFC 4867), 16 kHz mono telephony/IMS audio.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comments

pub max_red: Option<u32>,

/// AMR-WB specific parameter (RFC 4867).
///

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make it clearer this is just for parsing and we don't support it

}

if c0.channels != c1.channels {
if !Self::channels_match(c0, c1) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not related, leave alone

return true;
}

if c0.codec == Codec::AmrWb && c1.codec == Codec::AmrWb {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, this is weird.

Comment thread src/format/payload_params.rs Outdated
return None;
}

// Interleaving and robust sorting add RTP payload fields/layouts that

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put these higher up?

Comment thread src/rtp/mtime.rs
pub const FORTY_EIGHT_KHZ: Frequency = Self::make(48_000);

/// Cycles in a second of a 16 kHz signal.
pub const SIXTEEN_KHZ: Frequency = Self::make(16_000);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will be available in G.722

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant