19 if (sample_rate <= 0 || bitrate <= 0) {
32 codec->
encoder = opus_encoder_create(sample_rate, 1, (
int)application, &error);
33 if (error != OPUS_OK || !codec->
encoder) {
40 error = opus_encoder_ctl(codec->
encoder, OPUS_SET_BITRATE(bitrate));
41 if (error != OPUS_OK) {
43 opus_encoder_destroy(codec->
encoder);
53 log_debug(
"Opus encoder created: sample_rate=%d, bitrate=%d bps", sample_rate, bitrate);
63 if (sample_rate <= 0) {
76 codec->
decoder = opus_decoder_create(sample_rate, 1, &error);
77 if (error != OPUS_OK || !codec->
decoder) {
88 log_debug(
"Opus decoder created: sample_rate=%d", sample_rate);
99 if (!codec || !codec->
encoder || !samples || num_samples <= 0 || !out_data || out_size == 0) {
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) {
116 if (encoded_bytes == 0) {
121 return (
size_t)encoded_bytes;
129 int out_num_samples) {
130 if (!codec || !codec->
decoder || !out_samples || out_num_samples <= 0) {
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) {
140 int samples = opus_decode_float(codec->
decoder, NULL, 0, out_samples, out_num_samples, 0);
149 int samples = opus_decode_float(codec->
decoder, data, (opus_int32)data_len, out_samples, out_num_samples, 0);
164 if (!codec || !codec->
encoder || bitrate <= 0) {
166 (
void *)(codec ? codec->encoder : NULL), bitrate);
169 int error = opus_encoder_ctl(codec->
encoder, OPUS_SET_BITRATE(bitrate));
170 if (error != OPUS_OK) {
175 log_debug(
"Opus bitrate changed to %d bps", bitrate);
181 if (!codec || !codec->
encoder) {
186 opus_int32 bitrate = 0;
187 int error = opus_encoder_ctl(codec->
encoder, OPUS_GET_BITRATE(&bitrate));
188 if (error != OPUS_OK) {
197 if (!codec || !codec->
encoder) {
201 int error = opus_encoder_ctl(codec->
encoder, OPUS_SET_DTX(enable ? 1 : 0));
202 if (error != OPUS_OK) {
206 log_debug(
"Opus DTX %s", enable ?
"enabled" :
"disabled");
221 opus_encoder_destroy(codec->
encoder);
226 opus_decoder_destroy(codec->
decoder);
⚠️‼️ Error and/or exit() when things go bad.
opus_codec_t * opus_codec_create_decoder(int sample_rate)
Create an Opus decoder.
asciichat_error_t opus_codec_set_bitrate(opus_codec_t *codec, int bitrate)
Set encoder bitrate.
opus_application_t
Application mode for opus encoder.
int opus_codec_decode(opus_codec_t *codec, const uint8_t *data, size_t data_len, float *out_samples, int out_num_samples)
Decode Opus audio frame.
opus_codec_t * opus_codec_create_encoder(opus_application_t application, int sample_rate, int bitrate)
Create an Opus encoder.
int opus_codec_get_bitrate(opus_codec_t *codec)
Get current encoder bitrate.
asciichat_error_t opus_codec_set_dtx(opus_codec_t *codec, int enable)
Enable/disable DTX (Discontinuous Transmission)
void opus_codec_destroy(opus_codec_t *codec)
Destroy an Opus codec instance.
size_t opus_codec_encode(opus_codec_t *codec, const float *samples, int num_samples, uint8_t *out_data, size_t out_size)
Encode audio frame with Opus.
#define SAFE_MALLOC(size, cast)
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it.
asciichat_error_t
Error and exit codes - unified status values (0-255)
#define LOG_RATE_VERY_FAST
Log rate limit: 0.1 seconds (100,000 microseconds) - for very high frequency operations.
#define log_debug_every(interval_us, fmt,...)
Rate-limited DEBUG logging.
#define log_debug(...)
Log a DEBUG message.
Opus audio codec wrapper for real-time encoding/decoding.
Opus codec context for encoding or decoding.
uint8_t * tmp_buffer
Temporary buffer for internal use.
int bitrate
Bitrate in bits per second (encoder only)
int sample_rate
Sample rate in Hz (e.g., 44100)
OpusEncoder * encoder
Encoder state (NULL if decoder)
OpusDecoder * decoder
Decoder state (NULL if encoder)