-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmultistream_encoder_controls.go
More file actions
321 lines (275 loc) · 9.81 KB
/
multistream_encoder_controls.go
File metadata and controls
321 lines (275 loc) · 9.81 KB
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
package gopus
import "github.com/thesyncim/gopus/types"
// SetFrameSize sets the frame size in samples at 48kHz.
//
// Valid sizes are 120, 240, 480, 960, 1920, 2880, 3840, 4800, and 5760.
func (e *MultistreamEncoder) SetFrameSize(samples int) error {
if err := validateFrameSize(samples, e.application); err != nil {
return err
}
e.frameSize = samples
return nil
}
// FrameSize returns the current frame size in samples at 48kHz.
func (e *MultistreamEncoder) FrameSize() int {
return e.frameSize
}
// SetDNNBlob loads the optional libopus USE_WEIGHTS_FILE encoder model blob.
//
// The loaded blob is validated using libopus-style weights-record framing and
// retained across Reset(), matching libopus USE_WEIGHTS_FILE control lifetime.
func (e *MultistreamEncoder) SetDNNBlob(data []byte) error {
blob, err := cloneEncoderDNNBlobForControl(data)
if err != nil {
return err
}
e.dnnBlob = blob
e.enc.SetDNNBlob(blob)
return nil
}
// SetQEXT toggles the libopus ENABLE_QEXT encoder extension.
func (e *MultistreamEncoder) SetQEXT(enabled bool) error {
e.enc.SetQEXT(enabled)
return nil
}
// QEXT reports whether the optional extended-precision theta path is enabled.
func (e *MultistreamEncoder) QEXT() (bool, error) {
return e.enc.QEXT(), nil
}
// SetExpertFrameDuration sets the preferred frame duration policy for multistream encoding.
func (e *MultistreamEncoder) SetExpertFrameDuration(duration ExpertFrameDuration) error {
return setExpertFrameDuration(duration, &e.expertFrameDuration, e.SetFrameSize)
}
// ExpertFrameDuration returns the current multistream expert frame duration policy.
func (e *MultistreamEncoder) ExpertFrameDuration() ExpertFrameDuration {
return e.expertFrameDuration
}
// SetBitrate sets the total target bitrate in bits per second.
//
// The bitrate is distributed across streams with coupled streams getting
// proportionally more bits than mono streams.
//
// Valid total range is 6000 to 510000*channels bits per second.
func (e *MultistreamEncoder) SetBitrate(bitrate int) error {
if err := validateBitrate(bitrate, 510000*e.channels); err != nil {
return err
}
e.enc.SetBitrate(bitrate)
return nil
}
// Bitrate returns the current total target bitrate in bits per second.
func (e *MultistreamEncoder) Bitrate() int {
return e.enc.Bitrate()
}
// SetComplexity sets the encoder's computational complexity for all streams.
//
// complexity must be 0-10, where:
// - 0-1: Minimal processing, fastest encoding
// - 2-4: Basic analysis, good for real-time with limited CPU
// - 5-7: Moderate analysis, balanced quality/speed
// - 8-10: Thorough analysis, highest quality
//
// Returns ErrInvalidComplexity if out of range.
func (e *MultistreamEncoder) SetComplexity(complexity int) error {
if err := validateComplexity(complexity); err != nil {
return err
}
e.enc.SetComplexity(complexity)
return nil
}
// Complexity returns the current complexity setting.
func (e *MultistreamEncoder) Complexity() int {
return e.enc.Complexity()
}
// SetBitrateMode sets the multistream encoder bitrate control mode.
func (e *MultistreamEncoder) SetBitrateMode(mode BitrateMode) error {
if err := validateBitrateMode(mode); err != nil {
return err
}
e.enc.SetBitrateMode(mode)
return nil
}
// BitrateMode returns the active bitrate control mode.
func (e *MultistreamEncoder) BitrateMode() BitrateMode {
return e.enc.BitrateMode()
}
// SetVBR enables or disables VBR mode.
//
// Disabling VBR switches to CBR. Enabling VBR restores VBR while preserving
// the current VBR constraint state.
func (e *MultistreamEncoder) SetVBR(enabled bool) {
e.enc.SetVBR(enabled)
}
// VBR reports whether VBR mode is enabled.
func (e *MultistreamEncoder) VBR() bool {
return e.enc.VBR()
}
// SetVBRConstraint enables or disables constrained VBR mode.
// This setting is remembered even while VBR is disabled.
func (e *MultistreamEncoder) SetVBRConstraint(constrained bool) {
e.enc.SetVBRConstraint(constrained)
}
// VBRConstraint reports whether constrained VBR mode is enabled.
func (e *MultistreamEncoder) VBRConstraint() bool {
return e.enc.VBRConstraint()
}
// SetFEC enables or disables in-band Forward Error Correction for all streams.
//
// When enabled, the encoders include redundant information for loss recovery.
func (e *MultistreamEncoder) SetFEC(enabled bool) {
e.enc.SetFEC(enabled)
}
// FECEnabled returns whether FEC is enabled.
func (e *MultistreamEncoder) FECEnabled() bool {
return e.enc.FECEnabled()
}
// SetDTX enables or disables Discontinuous Transmission for all streams.
//
// When enabled, the encoders reduce bitrate during silence by emitting
// 1-byte TOC-only packets. The decoder handles CNG (Comfort Noise Generation).
func (e *MultistreamEncoder) SetDTX(enabled bool) {
e.enc.SetDTX(enabled)
}
// DTXEnabled returns whether DTX is enabled.
func (e *MultistreamEncoder) DTXEnabled() bool {
return e.enc.DTXEnabled()
}
// SetPacketLoss sets expected packet loss percentage for all stream encoders.
//
// lossPercent must be in the range [0, 100].
func (e *MultistreamEncoder) SetPacketLoss(lossPercent int) error {
if err := validatePacketLoss(lossPercent); err != nil {
return err
}
e.enc.SetPacketLoss(lossPercent)
return nil
}
// PacketLoss returns expected packet loss percentage.
func (e *MultistreamEncoder) PacketLoss() int {
return e.enc.PacketLoss()
}
// SetBandwidth sets the target audio bandwidth.
func (e *MultistreamEncoder) SetBandwidth(bw Bandwidth) error {
if err := validateBandwidth(bw); err != nil {
return err
}
e.enc.SetBandwidth(types.Bandwidth(bw))
return nil
}
// Bandwidth returns the currently configured target bandwidth.
func (e *MultistreamEncoder) Bandwidth() Bandwidth {
return Bandwidth(e.enc.Bandwidth())
}
// SetForceChannels forces channel count on all stream encoders.
//
// channels must be -1 (auto), 1 (mono), or 2 (stereo).
func (e *MultistreamEncoder) SetForceChannels(channels int) error {
if err := validateForceChannels(channels); err != nil {
return err
}
e.enc.SetForceChannels(channels)
return nil
}
// ForceChannels returns the forced channel count (-1 = auto).
func (e *MultistreamEncoder) ForceChannels() int {
return e.enc.ForceChannels()
}
// SetPredictionDisabled toggles inter-frame prediction on all stream encoders.
func (e *MultistreamEncoder) SetPredictionDisabled(disabled bool) {
e.enc.SetPredictionDisabled(disabled)
}
// PredictionDisabled reports whether inter-frame prediction is disabled.
func (e *MultistreamEncoder) PredictionDisabled() bool {
return e.enc.PredictionDisabled()
}
// SetPhaseInversionDisabled toggles stereo phase inversion on all stream encoders.
func (e *MultistreamEncoder) SetPhaseInversionDisabled(disabled bool) {
e.enc.SetPhaseInversionDisabled(disabled)
}
// PhaseInversionDisabled reports whether stereo phase inversion is disabled.
func (e *MultistreamEncoder) PhaseInversionDisabled() bool {
return e.enc.PhaseInversionDisabled()
}
// Reset clears the encoder state for a new stream.
// Call this when starting to encode a new audio stream.
func (e *MultistreamEncoder) Reset() {
e.enc.Reset()
e.encodedOnce = false
}
// Channels returns the number of audio channels.
func (e *MultistreamEncoder) Channels() int {
return e.channels
}
// SampleRate returns the sample rate in Hz.
func (e *MultistreamEncoder) SampleRate() int {
return e.sampleRate
}
// Streams returns the total number of elementary streams.
func (e *MultistreamEncoder) Streams() int {
return e.enc.Streams()
}
// CoupledStreams returns the number of coupled (stereo) streams.
func (e *MultistreamEncoder) CoupledStreams() int {
return e.enc.CoupledStreams()
}
// GetFinalRange returns the final range coder state for all streams.
// The values from all streams are XOR combined to produce a single verification value.
// This matches libopus OPUS_GET_FINAL_RANGE for multistream encoders.
// Must be called after Encode() to get a meaningful value.
func (e *MultistreamEncoder) GetFinalRange() uint32 {
return e.enc.GetFinalRange()
}
// FinalRange returns the final range coder state.
func (e *MultistreamEncoder) FinalRange() uint32 {
return e.GetFinalRange()
}
// Lookahead returns the encoder's algorithmic delay in samples.
//
// Matches libopus OPUS_GET_LOOKAHEAD behavior:
// - Base lookahead is Fs/400 (2.5ms)
// - Delay compensation Fs/250 is included for VoIP/Audio
// - Delay compensation is omitted for LowDelay
func (e *MultistreamEncoder) Lookahead() int {
return lookaheadSamples(e.sampleRate, e.application)
}
// Signal returns the current signal type hint.
// Returns SignalAuto, SignalVoice, or SignalMusic.
func (e *MultistreamEncoder) Signal() Signal {
return Signal(e.enc.Signal())
}
// SetSignal sets the signal type hint for all stream encoders.
// Use SignalVoice for speech content, SignalMusic for music content,
// or SignalAuto (default) for automatic detection.
func (e *MultistreamEncoder) SetSignal(signal Signal) error {
if err := validateSignal(signal); err != nil {
return err
}
e.enc.SetSignal(types.Signal(signal))
return nil
}
// SetMaxBandwidth sets the maximum bandwidth limit for all stream encoders.
// The actual bandwidth will be clamped to this limit.
func (e *MultistreamEncoder) SetMaxBandwidth(bw Bandwidth) error {
if err := validateBandwidth(bw); err != nil {
return err
}
e.enc.SetMaxBandwidth(types.Bandwidth(bw))
return nil
}
// MaxBandwidth returns the maximum bandwidth limit.
func (e *MultistreamEncoder) MaxBandwidth() Bandwidth {
return Bandwidth(e.enc.MaxBandwidth())
}
// SetLSBDepth sets the input signal's LSB depth for all stream encoders.
// Valid range is 8-24 bits. This affects DTX sensitivity.
// Returns an error if the depth is out of range.
func (e *MultistreamEncoder) SetLSBDepth(depth int) error {
if err := validateLSBDepth(depth); err != nil {
return err
}
return e.enc.SetLSBDepth(depth)
}
// LSBDepth returns the current LSB depth setting.
func (e *MultistreamEncoder) LSBDepth() int {
return e.enc.LSBDepth()
}