Skip to main content

opus_pure/
config.rs

1//! Encoder and decoder configuration types.
2
3/// What the encoder is being asked to optimise for, fixed when it is created.
4///
5/// This is the one setting that cannot be changed afterwards, because it
6/// decides which coding layers the encoder is allowed to use at all. It biases
7/// the SILK/CELT decision rather than dictating it: [`Audio`](Self::Audio) and
8/// [`Voip`](Self::Voip) both reach all three modes, and speech still codes as
9/// SILK under `Audio` when the content analysis says so.
10///
11/// The discriminants are libopus's `OPUS_APPLICATION_*` values, so a caller
12/// bridging to a C API can cast between the two.
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum Application {
15    /// Speech over a network. Shifts the mode threshold 8 kHz toward SILK
16    /// (`opus_encoder.c`), so borderline content codes as speech, and enables
17    /// the speech-oriented machinery: the analysis-driven bandwidth cap, DTX,
18    /// and in-band FEC being worth spending bits on.
19    Voip = 2048,
20    /// General audio, and the right default when the content is unknown or
21    /// mixed. Favours reproducing the input over making speech intelligible at
22    /// low rates.
23    Audio = 2049,
24    /// Lowest achievable latency, at a cost in quality.
25    ///
26    /// Forces CELT for every frame and removes the 2.5 ms CELT lookahead that
27    /// the other two spend to keep the layers aligned across a mode switch
28    /// (`opus_encoder.c:1904`), since with no mode switching there is nothing to
29    /// align. That lookahead is part of what
30    /// [`OpusHead::RECOMMENDED_PRE_SKIP`](crate::ogg::OpusHead::RECOMMENDED_PRE_SKIP)
31    /// counts, so a stream encoded this way has less delay to skip.
32    RestrictedLowDelay = 2051,
33}
34
35/// How the encoder is allowed to vary the size of each packet.
36///
37/// Opus is a variable-rate codec, and the bitrate a caller sets is an average
38/// the encoder spends around rather than a size it emits every time. This
39/// chooses how much it is allowed to deviate.
40///
41/// [`ConstrainedVbr`](Self::ConstrainedVbr) is the default, and matches
42/// libopus. The difference from [`Vbr`](Self::Vbr) only shows up on content
43/// whose difficulty changes quickly: constrained VBR keeps a reservoir so that
44/// any window of packets stays near the target, which is what a network with a
45/// fixed budget needs, while unconstrained VBR spends whatever a frame is
46/// worth. For encoding a file, where nothing downstream is metering the rate,
47/// unconstrained is usually the better picture per byte โ€” it is what `opusenc`
48/// uses by default.
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50pub enum RateControl {
51    /// Spend what each frame is worth, with no reservoir. Best quality per byte
52    /// over a whole file; the instantaneous rate can wander a long way from the
53    /// target.
54    Vbr,
55    /// Vary per packet, but hold a reservoir so any short window stays near the
56    /// target. The default, and libopus's.
57    ConstrainedVbr,
58    /// One size for every packet. Costs roughly a twelfth of the working
59    /// bitrate against the other two, because the encoder can no longer move
60    /// bits from an easy frame to a hard one; pick it only when something
61    /// downstream genuinely needs a fixed packet size.
62    Cbr,
63}
64
65impl RateControl {
66    /// Whether this is [`Cbr`](Self::Cbr), which is the distinction almost
67    /// every decision inside the encoder actually turns on.
68    pub(crate) fn is_cbr(self) -> bool {
69        matches!(self, RateControl::Cbr)
70    }
71}
72
73/// OPUS_SET_SIGNAL hint: bias mode selection toward speech or music. `None` =
74/// OPUS_AUTO (let the analysis decide).
75///
76/// Setting this pins the answer the content analysis would otherwise reach, so
77/// it also makes the analysis cheap to skip. That matters for
78/// [`encode_parallel`](crate::encode_parallel), where every worker would
79/// otherwise have to re-derive it from its own warm-up audio.
80#[derive(Debug, Clone, Copy, PartialEq, Eq)]
81pub enum Signal {
82    /// Speech: code it as SILK, or as hybrid where the rate allows.
83    Voice,
84    /// Music: code it as CELT.
85    Music,
86}
87
88/// The audio bandwidth a packet carries, which is what Opus varies instead of
89/// the sample rate.
90///
91/// An Opus decoder always produces audio at the rate it was created with; a
92/// narrowband packet is not a slower stream, it is one whose upper spectrum was
93/// never coded. Each name gives the audio bandwidth, and the sample rate that
94/// would be needed to represent it: 4 kHz of audio needs 8 kHz of sampling.
95///
96/// The encoder chooses this per packet from the bitrate, and a caller normally
97/// leaves it alone. To constrain it, prefer
98/// [`max_bandwidth`](crate::OpusEncoder::max_bandwidth), which caps the
99/// automatic choice, over
100/// [`force_bandwidth`](crate::OpusEncoder::force_bandwidth), which overrides it
101/// and can spend bits on spectrum the rate cannot afford.
102///
103/// The discriminants are libopus's `OPUS_BANDWIDTH_*` values.
104#[derive(Debug, Clone, Copy, PartialEq, Eq)]
105pub enum Bandwidth {
106    /// 4 kHz of audio, as an 8 kHz sample rate would carry.
107    Narrowband = 1101,
108    /// 6 kHz of audio (12 kHz sampling). Retained because it appears in the
109    /// bitstream and a decoder must handle it, but libopus's encoder no longer
110    /// selects it automatically and neither does this one.
111    Mediumband = 1102,
112    /// 8 kHz of audio (16 kHz sampling), the usual top of speech coding.
113    Wideband = 1103,
114    /// 12 kHz of audio (24 kHz sampling). Hybrid and CELT only.
115    Superwideband = 1104,
116    /// 20 kHz of audio (48 kHz sampling), the full audible range. Hybrid and
117    /// CELT only.
118    Fullband = 1105,
119}
120
121/// Which coding layers a packet actually used.
122///
123/// Opus is two codecs behind one bitstream, and the TOC byte says which of them
124/// coded a given packet. A caller normally does not care โ€” the decoder handles
125/// all three โ€” but the layer decides what some other operations mean. In-band
126/// FEC, in particular, only exists in SILK and hybrid packets, so
127/// [`OpusDecoder::decode_fec`](crate::OpusDecoder::decode_fec) on a
128/// [`CeltOnly`](Self::CeltOnly) packet can only conceal.
129///
130/// RFC 6716 ยง3.1 fixes these three, so the set will not grow.
131#[derive(Debug, Clone, Copy, PartialEq, Eq)]
132pub enum OpusMode {
133    /// SILK alone: speech, up to wideband, 10 ms and longer.
134    SilkOnly,
135    /// SILK below and CELT above: speech at super-wideband or fullband.
136    Hybrid,
137    /// CELT alone: music, any bandwidth, and every frame shorter than 10 ms.
138    CeltOnly,
139}