1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//! CELT wideband audio codec: MDCT + psychoacoustic bit allocation for Opus's music mode.
//!
//! ## What
//!
//! Implements one encode/decode cycle for a single Opus CELT audio frame.
//! Each frame runs the full existing perceptual codec pipeline from
//! [`crate::codecs::perceptual`]:
//!
//! 1. MDCT analysis (window size = frame length).
//! 2. Psychoacoustic masking → per-band importance and allowed noise.
//! 3. Bit allocation: distribute the bit budget across bands proportional to
//! perceptual importance.
//! 4. Scalar quantisation of MDCT coefficients per band.
//!
//! Decoding runs the inverse: dequantise → IMDCT with overlap-add.
//!
//! ## Why
//!
//! CELT is the wideband, low-latency half of Opus. It analyses and codes the
//! entire spectrum in one MDCT block matching the frame length, making it ideal
//! for music and generic audio. Unlike SILK, it makes no speech-specific
//! assumptions.
//!
//! ## Relationship to `PerceptualCodec`
//!
//! [`celt_encode_frame`] is essentially one call to the internal
//! `encode_segment` helper from `PerceptualCodec`, scoped to a single Opus
//! frame. The [`CeltEncodedFrame`] type mirrors
//! [`crate::codecs::perceptual::codec::EncodedSegment`] with the addition of
//! the per-frame sample count.
use ;
use NonEmptyVec;
use ;
use crate;
use crate;
use crate::;
// ── CeltEncodedFrame ──────────────────────────────────────────────────────────
/// One CELT-encoded Opus audio frame.
///
/// The in-memory representation is equivalent to
/// [`crate::codecs::perceptual::codec::EncodedSegment`] scoped to a single
/// Opus frame. The `window_size` equals the frame length, so `n_frames` is
/// typically 1 or 2 depending on how the MDCT hop interacts with the frame
/// boundary.
///
/// Everything needed to reconstruct the frame is self-contained: MDCT
/// parameters, per-band bit allocation, and the original sample count.
// ── celt_encode_frame ─────────────────────────────────────────────────────────
/// Encodes a single CELT audio frame.
///
/// The frame is analysed with the MDCT, processed through the psychoacoustic
/// model, and the resulting coefficients are quantised with the per-band
/// allocation from [`allocate_bits`].
///
/// # Arguments
/// - `frame` – Mono audio frame to encode.
/// - `band_layout` – Perceptual frequency-band partitioning (e.g. [`crate::BandLayout::celt`]).
/// - `psych_config` – Psychoacoustic masking configuration. Must have the same
/// number of weights as `band_layout.len()`.
/// - `window` – MDCT window function. [`spectrograms::WindowType::Hanning`] is a
/// reasonable default.
/// - `window_size` – Explicit MDCT window size (typically `= frame_length`, i.e.
/// the number of samples in `frame`). When `None`, an automatic size ≤ 2048 is
/// chosen.
/// - `bit_budget` – Total bits to allocate across all bands.
/// - `min_bits_per_band` – Minimum bits guaranteed to every band (typically 1).
///
/// # Errors
/// Returns [`crate::AudioSampleError::Parameter`] if `frame` is not mono, is
/// fewer than 4 samples, or `psych_config` is incompatible with `band_layout`.
// ── celt_decode_frame ─────────────────────────────────────────────────────────
/// Decodes a CELT-encoded Opus audio frame.
///
/// Dequantises the MDCT coefficients and applies the IMDCT with overlap-add to
/// reconstruct the time-domain signal.
///
/// # Arguments
/// - `frame` – A CELT frame produced by [`celt_encode_frame`].
/// - `sample_rate` – Sample rate for the returned audio.
///
/// # Errors
/// Returns [`crate::AudioSampleError`] if the IMDCT reconstruction fails.
///
/// # Returns
/// A `Vec<f32>` of `frame.n_samples` reconstructed PCM samples.