19 if (sample_rate <= 0 || bitrate <= 0) {
20 SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid codec parameters: sample_rate=%d, bitrate=%d", sample_rate, bitrate);
24 opus_codec_t *codec = SAFE_MALLOC(
sizeof(opus_codec_t), opus_codec_t *);
26 SET_ERRNO(ERROR_MEMORY,
"Failed to allocate opus codec context");
32 codec->encoder = opus_encoder_create(sample_rate, 1, (
int)application, &error);
33 if (error != OPUS_OK || !codec->encoder) {
34 SET_ERRNO(ERROR_AUDIO,
"Failed to create Opus encoder: %s", opus_strerror(error));
40 error = opus_encoder_ctl(codec->encoder, OPUS_SET_BITRATE(bitrate));
41 if (error != OPUS_OK) {
42 SET_ERRNO(ERROR_AUDIO,
"Failed to set Opus bitrate: %s", opus_strerror(error));
43 opus_encoder_destroy(codec->encoder);
48 codec->decoder = NULL;
49 codec->sample_rate = sample_rate;
50 codec->bitrate = bitrate;
51 codec->tmp_buffer = NULL;
53 log_debug(
"Opus encoder created: sample_rate=%d, bitrate=%d bps", sample_rate, bitrate);
63 if (sample_rate <= 0) {
64 SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid sample rate: %d", sample_rate);
68 opus_codec_t *codec = SAFE_MALLOC(
sizeof(opus_codec_t), opus_codec_t *);
70 SET_ERRNO(ERROR_MEMORY,
"Failed to allocate opus codec context");
76 codec->decoder = opus_decoder_create(sample_rate, 1, &error);
77 if (error != OPUS_OK || !codec->decoder) {
78 SET_ERRNO(ERROR_AUDIO,
"Failed to create Opus decoder: %s", opus_strerror(error));
83 codec->encoder = NULL;
84 codec->sample_rate = sample_rate;
86 codec->tmp_buffer = NULL;
88 log_debug(
"Opus decoder created: sample_rate=%d", sample_rate);
97size_t opus_codec_encode(opus_codec_t *codec,
const float *samples,
int num_samples, uint8_t *out_data,
99 if (!codec || !codec->encoder || !samples || num_samples <= 0 || !out_data || out_size == 0) {
100 SET_ERRNO(ERROR_INVALID_PARAM,
101 "Invalid encode parameters: codec=%p, encoder=%p, samples=%p, num_samples=%d, out_data=%p, "
103 (
void *)codec, (
void *)(codec ? codec->encoder : NULL), (
const void *)samples, num_samples,
104 (
void *)out_data, out_size);
109 opus_int32 encoded_bytes = opus_encode_float(codec->encoder, samples, num_samples, out_data, (opus_int32)out_size);
111 if (encoded_bytes < 0) {
112 SET_ERRNO(ERROR_AUDIO,
"Opus encoding failed: %s", opus_strerror((
int)encoded_bytes));
116 if (encoded_bytes == 0) {
118 log_debug_every(LOG_RATE_VERY_FAST,
"Opus DTX frame (silence detected)");
121 return (
size_t)encoded_bytes;
128int opus_codec_decode(opus_codec_t *codec,
const uint8_t *data,
size_t data_len,
float *out_samples,
129 int out_num_samples) {
130 if (!codec || !codec->decoder || !out_samples || out_num_samples <= 0) {
131 SET_ERRNO(ERROR_INVALID_PARAM,
132 "Invalid decode parameters: codec=%p, decoder=%p, out_samples=%p, out_num_samples=%d", (
void *)codec,
133 (
void *)(codec ? codec->decoder : NULL), (
void *)out_samples, out_num_samples);
138 if (!data || data_len == 0) {
139 log_debug_every(LOG_RATE_VERY_FAST,
"Opus PLC (Packet Loss Concealment)");
140 int samples = opus_decode_float(codec->decoder, NULL, 0, out_samples, out_num_samples, 0);
142 SET_ERRNO(ERROR_AUDIO,
"Opus PLC failed: %s", opus_strerror(samples));
149 int samples = opus_decode_float(codec->decoder, data, (opus_int32)data_len, out_samples, out_num_samples, 0);
152 SET_ERRNO(ERROR_AUDIO,
"Opus decoding failed: %s", opus_strerror(samples));
164 if (!codec || !codec->encoder || bitrate <= 0) {
165 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid bitrate parameters: codec=%p, encoder=%p, bitrate=%d", (
void *)codec,
166 (
void *)(codec ? codec->encoder : NULL), bitrate);
169 int error = opus_encoder_ctl(codec->encoder, OPUS_SET_BITRATE(bitrate));
170 if (error != OPUS_OK) {
171 return SET_ERRNO(ERROR_AUDIO,
"Failed to set Opus bitrate: %s", opus_strerror(error));
174 codec->bitrate = bitrate;
175 log_debug(
"Opus bitrate changed to %d bps", bitrate);